Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'package:app_finance/_classes/herald/app_design.dart';
5 : import 'package:app_finance/_classes/herald/app_locale.dart';
6 : import 'package:app_finance/_classes/herald/app_zoom.dart';
7 : import 'package:app_finance/_classes/structure/navigation/app_menu.dart';
8 : import 'package:app_finance/_configs/custom_text_theme.dart';
9 : import 'package:app_finance/_configs/theme_helper.dart';
10 : import 'package:app_finance/_ext/build_context_ext.dart';
11 : import 'package:app_finance/design/wrapper/tap_widget.dart';
12 : import 'package:app_finance/design/wrapper/text_wrapper.dart';
13 : import 'package:app_finance/design/button/toolbar_button_widget.dart';
14 : import 'package:material_ui/material_ui.dart';
15 : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
16 : import 'package:flutter_grid_layout/flutter_grid_layout.dart';
17 : import 'package:provider/provider.dart';
18 :
19 : class BaseHeaderWidget extends StatelessWidget {
20 : final String? tooltip;
21 : final String? route;
22 : final String? searchRoute;
23 : final String? sortRoute;
24 : final String title;
25 : final double width;
26 : final double? total;
27 : final bool hasExpand;
28 : final bool hasMetrics;
29 : final bool toExpand;
30 : final Function? expand;
31 :
32 6 : const BaseHeaderWidget({
33 : super.key,
34 : required this.tooltip,
35 : required this.route,
36 : required this.title,
37 : required this.total,
38 : required this.width,
39 : this.hasExpand = false,
40 : this.hasMetrics = true,
41 : this.toExpand = true,
42 : this.expand,
43 : this.searchRoute,
44 : this.sortRoute,
45 6 : }) : assert(hasExpand && expand != null || !hasExpand);
46 :
47 6 : @override
48 : Widget build(BuildContext context) {
49 6 : double indent = ThemeHelper.getIndent();
50 6 : final textTheme = context.textTheme;
51 6 : final colorScheme = context.colorScheme;
52 6 : final nav = Navigator.of(context);
53 18 : final isWide = Provider.of<AppZoom>(context, listen: false).value > 1.5;
54 6 : final bnShift = Offset(-4, isWide ? -8 : 0);
55 12 : final metrics = AppMenu.metrics(route);
56 6 : final subStyle = isWide ? textTheme.bodySmall : textTheme.headlineSmall;
57 18 : final subHeight = ThemeHelper.getTextHeight(Text(title, style: subStyle));
58 6 : final numStyle = isWide ? textTheme.numberSmall : textTheme.numberLarge;
59 24 : final numHeight = ThemeHelper.getTextHeight(Text(total.toString(), style: numStyle));
60 6 : final isSearchRoute = searchRoute != null && searchRoute!.isNotEmpty;
61 8 : final isSortRoute = sortRoute != null && sortRoute!.isNotEmpty;
62 6 : return TapWidget(
63 6 : tooltip: tooltip,
64 12 : route: RouteSettings(name: route),
65 6 : child: Container(
66 12 : padding: EdgeInsets.all(indent / 2),
67 18 : height: numHeight + subHeight + (hasMetrics ? indent : -indent - 2),
68 : width: double.infinity,
69 12 : color: colorScheme.inverseSurface.withValues(alpha: 0.1),
70 6 : child: GridContainer(
71 6 : alignment: AppDesign.getAlignment<MainAxisAlignment>(),
72 13 : rows: [null, ThemeHelper.barHeight, if (hasExpand || isSearchRoute || isSortRoute) ThemeHelper.barHeight],
73 6 : columns: [subHeight, null],
74 6 : children: [
75 6 : GridItem(
76 : start: const Size(0, 0),
77 6 : end: hasMetrics ? const Size(1, 1) : const Size(2, 1),
78 12 : child: TextWrapper(title, style: subStyle),
79 : ),
80 6 : GridItem(
81 : start: const Size(0, 1),
82 6 : end: hasMetrics ? const Size(1, 2) : const Size(2, 2),
83 6 : child: FittedBox(
84 : fit: BoxFit.scaleDown,
85 6 : alignment: AppDesign.isRightToLeft() ? Alignment.centerRight : Alignment.centerLeft,
86 24 : child: TextWrapper(total != null ? total!.toCurrency(withPattern: false) : '', style: numStyle),
87 : ),
88 : ),
89 6 : if (hasMetrics)
90 6 : GridItem(
91 : start: const Size(1, 0),
92 : end: const Size(2, 2),
93 6 : child: ToolbarButtonWidget(
94 18 : borderColor: context.colorScheme.onSecondaryContainer.withValues(alpha: 0.3),
95 : offset: bnShift,
96 : icon: Icons.stacked_bar_chart,
97 12 : color: context.colorScheme.onSecondaryContainer,
98 12 : tooltip: AppLocale.labels.metricsTooltip,
99 0 : onPressed: () => nav.pushNamed(metrics.name!, arguments: metrics.arguments),
100 18 : backgroundColor: context.colorScheme.surface.withValues(alpha: 0.3),
101 : ),
102 : ),
103 6 : if (hasExpand)
104 0 : GridItem(
105 : start: const Size(2, 0),
106 : end: const Size(3, 2),
107 0 : child: ToolbarButtonWidget(
108 0 : borderColor: context.colorScheme.onSecondaryContainer.withValues(alpha: 0.3),
109 : offset: bnShift,
110 : selectedIcon: Icons.expand,
111 0 : selectedColor: context.colorScheme.onSecondaryContainer,
112 0 : backgroundColor: context.colorScheme.surface.withValues(alpha: 0.3),
113 : icon: Icons.expand_less,
114 0 : color: context.colorScheme.primary.withValues(alpha: 0.6),
115 0 : tooltip: toExpand ? AppLocale.labels.expand : AppLocale.labels.collapse,
116 0 : onPressed: () => expand!(),
117 0 : isSelected: toExpand,
118 : ),
119 : ),
120 : if (isSearchRoute)
121 0 : GridItem(
122 : start: const Size(2, 0),
123 : end: const Size(3, 2),
124 0 : child: ToolbarButtonWidget(
125 0 : borderColor: context.colorScheme.onSecondaryContainer.withValues(alpha: 0.3),
126 : offset: bnShift,
127 0 : selectedColor: context.colorScheme.onSecondaryContainer,
128 0 : backgroundColor: context.colorScheme.surface.withValues(alpha: 0.3),
129 : icon: Icons.search,
130 0 : color: context.colorScheme.onSecondaryContainer,
131 0 : tooltip: AppLocale.labels.searchTooltip,
132 0 : onPressed: () => nav.pushNamed(searchRoute!),
133 : ),
134 : ),
135 : if (isSortRoute)
136 1 : GridItem(
137 : start: const Size(2, 0),
138 : end: const Size(3, 2),
139 1 : child: ToolbarButtonWidget(
140 3 : borderColor: context.colorScheme.onSecondaryContainer.withValues(alpha: 0.3),
141 : offset: bnShift,
142 2 : selectedColor: context.colorScheme.onSecondaryContainer,
143 3 : backgroundColor: context.colorScheme.surface.withValues(alpha: 0.3),
144 : icon: Icons.sort,
145 2 : color: context.colorScheme.onSecondaryContainer,
146 2 : tooltip: AppLocale.labels.sortTooltip,
147 0 : onPressed: () => nav.pushNamed(sortRoute!),
148 : ),
149 : ),
150 : ],
151 : ),
152 : ),
153 : );
154 : }
155 : }
|