Line data Source code
1 : // Copyright 2026 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_locale.dart';
5 : import 'package:app_finance/_classes/controller/focus_controller.dart';
6 : import 'package:app_finance/_classes/structure/bill_app_data.dart';
7 : import 'package:app_finance/_configs/theme_helper.dart';
8 : import 'package:app_finance/design/button/full_sized_button_widget.dart';
9 : import 'package:app_finance/design/button/link_widget.dart';
10 : import 'package:app_finance/design/form/simple_input.dart';
11 : import 'package:app_finance/design/wrapper/input_wrapper.dart';
12 : import 'package:app_finance/design/wrapper/single_scroll_wrapper.dart';
13 : import 'package:app_finance/pages/_interfaces/abstract_page_state.dart';
14 : import 'package:material_ui/material_ui.dart';
15 :
16 : class BillSplitPage extends StatefulWidget {
17 : final String uuid;
18 :
19 0 : const BillSplitPage({
20 : super.key,
21 : required this.uuid,
22 : });
23 :
24 0 : @override
25 0 : BillSplitPageState createState() => BillSplitPageState();
26 : }
27 :
28 : class BillSplitPageState extends AbstractPageState<BillSplitPage> {
29 : late FocusController focus;
30 : late TextEditingController description;
31 : late TextEditingController bill;
32 : String? budget;
33 :
34 0 : @override
35 : void initState() {
36 0 : super.initState();
37 0 : focus = FocusController();
38 0 : description = TextEditingController();
39 0 : bill = TextEditingController();
40 : }
41 :
42 0 : @override
43 : void dispose() {
44 0 : description.dispose();
45 0 : bill.dispose();
46 0 : super.dispose();
47 : }
48 :
49 0 : @override
50 0 : String getTitle() => AppLocale.labels.splitHeadline;
51 :
52 0 : @override
53 : String getButtonName() => '';
54 :
55 0 : @override
56 : Widget buildButton(BuildContext context, BoxConstraints constraints) {
57 0 : return Container();
58 : }
59 :
60 0 : void saveAction() {
61 0 : double amount = double.tryParse(bill.text) ?? 0.0;
62 0 : final item = state.getByUuid(widget.uuid).clone() as BillAppData;
63 0 : item.details -= amount;
64 0 : item.hasChild = true;
65 0 : state.update(item.uuid ?? '', item);
66 0 : final splitItem = item.clone();
67 0 : splitItem.uuid = null;
68 0 : splitItem.details = amount;
69 0 : splitItem.category = budget ?? item.category;
70 0 : splitItem.title = '${item.title}: ${description.text}';
71 0 : splitItem.childOf = item.uuid;
72 0 : state.add(splitItem);
73 0 : Navigator.of(context).pop();
74 : }
75 :
76 0 : @override
77 : Widget buildContent(BuildContext context, BoxConstraints constraints) {
78 0 : final indent = ThemeHelper.getIndent();
79 0 : final item = state.getByUuid(widget.uuid) as BillAppData;
80 0 : final width = ThemeHelper.getWidth(context, 2, constraints);
81 :
82 0 : return SingleScrollWrapper(
83 0 : controller: focus,
84 0 : child: Container(
85 0 : padding: EdgeInsets.all(indent),
86 0 : child: Column(
87 0 : children: [
88 0 : Align(
89 : alignment: Alignment.centerRight,
90 0 : child: LinkWidget(
91 0 : AppLocale.labels.btnCancel,
92 0 : onTap: () => Navigator.of(context).pop(),
93 : ),
94 : ),
95 : ThemeHelper.hIndent,
96 : // Form
97 0 : InputWrapper.text(
98 0 : title: AppLocale.labels.description,
99 0 : controller: description,
100 0 : tooltip: AppLocale.labels.descriptionTooltip,
101 : ),
102 0 : InputWrapper.text(
103 0 : title: AppLocale.labels.expense,
104 : isRequired: true,
105 0 : controller: bill,
106 0 : tooltip: AppLocale.labels.billSetTooltip,
107 : inputType: const TextInputType.numberWithOptions(decimal: true),
108 0 : formatter: [SimpleInputFormatter.filterDouble],
109 : ),
110 0 : InputWrapper(
111 : type: NamedInputType.budgetSelector,
112 : isRequired: true,
113 0 : value: state.getByUuid(budget ?? item.category),
114 0 : title: AppLocale.labels.budget,
115 0 : tooltip: AppLocale.labels.titleBudgetTooltip,
116 0 : state: state,
117 0 : onChange: (value) => setState(() => budget = value?.uuid),
118 0 : width: width - 2 * indent,
119 : ),
120 : ThemeHelper.hIndent,
121 0 : FullSizedButtonWidget(
122 0 : onPressed: saveAction,
123 0 : title: AppLocale.labels.saveSettingsTooltip,
124 : icon: Icons.save_outlined,
125 : ),
126 : ThemeHelper.formEndBox,
127 : ],
128 : ),
129 : ),
130 : );
131 : }
132 : }
|