Line data Source code
1 : // Copyright 2024 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/controller/focus_controller.dart';
5 : import 'package:app_finance/_classes/herald/app_design.dart';
6 : import 'package:app_finance/_classes/herald/app_locale.dart';
7 : import 'package:app_finance/_classes/structure/currency_app_data.dart';
8 : import 'package:app_finance/_configs/theme_helper.dart';
9 : import 'package:app_finance/design/form/simple_input.dart';
10 : import 'package:app_finance/design/wrapper/input_wrapper.dart';
11 : import 'package:app_finance/design/wrapper/single_scroll_wrapper.dart';
12 : import 'package:app_finance/pages/_interfaces/abstract_add_page.dart';
13 : import 'package:flutter/material.dart';
14 : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
15 :
16 : class CurrencyAddPage extends AbstractAddPage {
17 1 : const CurrencyAddPage({super.key});
18 :
19 0 : @override
20 0 : CurrencyAddPageState createState() => CurrencyAddPageState();
21 : }
22 :
23 : class CurrencyAddPageState extends AbstractAddPageState<CurrencyAddPage> {
24 : late FocusController focus;
25 : Currency? currencyFrom;
26 : Currency? currencyTo;
27 : late TextEditingController conversion;
28 :
29 0 : @override
30 : void initState() {
31 0 : focus = FocusController();
32 0 : conversion = TextEditingController(text: '');
33 0 : super.initState();
34 : }
35 :
36 0 : @override
37 : void dispose() {
38 0 : focus.dispose();
39 0 : conversion.dispose();
40 0 : super.dispose();
41 : }
42 :
43 0 : @override
44 0 : String getTitle() => AppLocale.labels.currencyAddHeadline;
45 :
46 0 : @override
47 0 : String getButtonName() => AppLocale.labels.currencyAddTooltip;
48 :
49 0 : @override
50 : bool hasFormErrors() {
51 0 : setState(() => hasError = currencyFrom == null ||
52 0 : currencyTo == null ||
53 0 : currencyFrom == currencyTo ||
54 0 : conversion.text.isEmpty ||
55 0 : double.tryParse(conversion.text) == 1.0);
56 0 : return hasError;
57 : }
58 :
59 0 : @override
60 : void updateStorage() {
61 0 : final exchange = CurrencyAppData(
62 0 : currency: currencyTo,
63 0 : currencyFrom: currencyFrom,
64 0 : details: double.tryParse(conversion.text) ?? 1.0,
65 : );
66 0 : state.update(exchange.uuid, exchange, true);
67 : }
68 :
69 0 : @override
70 : void triggerActionButton(NavigatorState nav) {
71 0 : setState(() {
72 0 : if (hasFormErrors()) {
73 : return;
74 : }
75 0 : updateStorage();
76 0 : nav.pop();
77 : });
78 : }
79 :
80 0 : @override
81 : Widget buildButton(BuildContext context, BoxConstraints constraints) {
82 0 : NavigatorState nav = Navigator.of(context);
83 0 : return FloatingActionButton(
84 : heroTag: 'currency_page_add',
85 0 : onPressed: () => triggerActionButton(nav),
86 0 : tooltip: getButtonName(),
87 : child: const Icon(Icons.save),
88 : );
89 : }
90 :
91 0 : @override
92 : Widget buildContent(BuildContext context, BoxConstraints constraints) {
93 0 : final indent = ThemeHelper.getIndent();
94 0 : return SingleScrollWrapper(
95 0 : controller: focus,
96 0 : child: Padding(
97 0 : padding: EdgeInsets.all(indent),
98 0 : child: Column(
99 0 : crossAxisAlignment: AppDesign.getAlignment(),
100 0 : children: [
101 0 : InputWrapper.currency(
102 : isRequired: true,
103 0 : showError: hasError && currencyFrom == null,
104 0 : value: currencyFrom,
105 0 : title: '${AppLocale.labels.currency} (${AppLocale.labels.from})',
106 0 : tooltip: AppLocale.labels.currencyTooltip,
107 0 : onChange: (value) => setState(() => currencyFrom = value),
108 : ),
109 0 : InputWrapper.currency(
110 : isRequired: true,
111 0 : showError: hasError && (currencyTo == null || currencyFrom == currencyTo),
112 0 : value: currencyTo,
113 0 : title: '${AppLocale.labels.currency} (${AppLocale.labels.to})',
114 0 : tooltip: AppLocale.labels.currencyTooltip,
115 0 : onChange: (value) => setState(() => currencyTo = value),
116 : ),
117 0 : InputWrapper.text(
118 0 : title: AppLocale.labels.currencyExchange(currencyFrom?.code ?? '?', currencyTo?.code ?? '?'),
119 0 : tooltip: AppLocale.labels.conversion,
120 : isRequired: true,
121 0 : showError: hasError && (conversion.text.isEmpty || double.tryParse(conversion.text) == 1.0),
122 0 : controller: conversion,
123 : inputType: const TextInputType.numberWithOptions(decimal: true),
124 0 : formatter: [
125 0 : SimpleInputFormatter.filterDouble,
126 : ],
127 : ),
128 : ThemeHelper.formEndBox,
129 : ],
130 : ),
131 : ),
132 : );
133 : }
134 : }
|