diff --git a/lib/ui/app/forms/decorated_form_field.dart b/lib/ui/app/forms/decorated_form_field.dart index 24c1b91ab..66c5222ba 100644 --- a/lib/ui/app/forms/decorated_form_field.dart +++ b/lib/ui/app/forms/decorated_form_field.dart @@ -10,6 +10,7 @@ class DecoratedFormField extends StatelessWidget { this.maxLines, this.textInputAction, this.onFieldSubmitted, + this.enabled, }); final TextEditingController controller; @@ -18,6 +19,7 @@ class DecoratedFormField extends StatelessWidget { final TextInputType keyboardType; final int maxLines; final bool autovalidate; + final bool enabled; final TextInputAction textInputAction; final ValueChanged onFieldSubmitted; @@ -36,6 +38,7 @@ class DecoratedFormField extends StatelessWidget { autovalidate: autovalidate, textInputAction: textInputAction, onFieldSubmitted: onFieldSubmitted, + enabled: enabled, ); } } diff --git a/lib/ui/company_gateway/edit/company_gateway_edit.dart b/lib/ui/company_gateway/edit/company_gateway_edit.dart index 8166c288a..01d90e4ca 100644 --- a/lib/ui/company_gateway/edit/company_gateway_edit.dart +++ b/lib/ui/company_gateway/edit/company_gateway_edit.dart @@ -7,6 +7,7 @@ import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/forms/color_picker.dart'; +import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/company_gateway/edit/company_gateway_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart'; @@ -218,6 +219,10 @@ class _CompanyGatewayEditState extends State viewModel: viewModel, companyGateway: companyGateway, ), + FeesEditor( + viewModel: viewModel, + companyGateway: companyGateway, + ), ], ), ], @@ -494,13 +499,13 @@ class _LimitEditorState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(localization.minLimit), - SizedBox(height: 10), - TextFormField( + DecoratedFormField( + label: localization.minLimit, enabled: _enableMin, controller: _minController, keyboardType: TextInputType.numberWithOptions(), ), + SizedBox(height: 10), CheckboxListTile( controlAffinity: ListTileControlAffinity.leading, activeColor: Theme.of(context).accentColor, @@ -524,13 +529,13 @@ class _LimitEditorState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(localization.maxLimit), - SizedBox(height: 10), - TextFormField( + DecoratedFormField( + label: localization.maxLimit, enabled: _enableMax, controller: _maxController, keyboardType: TextInputType.numberWithOptions(), ), + SizedBox(height: 10), CheckboxListTile( controlAffinity: ListTileControlAffinity.leading, activeColor: Theme.of(context).accentColor, @@ -555,3 +560,89 @@ class _LimitEditorState extends State { ); } } + +class FeesEditor extends StatefulWidget { + const FeesEditor({this.companyGateway, this.viewModel}); + + final CompanyGatewayEntity companyGateway; + final CompanyGatewayEditVM viewModel; + + @override + _FeesEditorState createState() => _FeesEditorState(); +} + +class _FeesEditorState extends State { + + final _amountController = TextEditingController(); + final _percentController = TextEditingController(); + final _capController = TextEditingController(); + + final List _controllers = []; + + @override + void dispose() { + _controllers.forEach((dynamic controller) { + controller.removeListener(_onChanged); + controller.dispose(); + }); + + super.dispose(); + } + + @override + void didChangeDependencies() { + + final List _controllers = [ + _amountController, + _percentController, + _capController, + ]; + + _controllers + .forEach((dynamic controller) => controller.removeListener(_onChanged)); + + + // TODO + + _controllers + .forEach((dynamic controller) => controller.addListener(_onChanged)); + + super.didChangeDependencies(); + } + + void _onChanged() { + final viewModel = widget.viewModel; + final companyGateway = viewModel.companyGateway; + + final updatedGateway = companyGateway.rebuild((b) => b + //..minLimit = _enableMin ? parseDouble(_minController.text.trim()) : null + //..maxLimit = _enableMax ? parseDouble(_maxController.text.trim()) : null + ); + + if (companyGateway != updatedGateway) { + viewModel.onChanged(updatedGateway); + } + } + + @override + Widget build(BuildContext context) { + final localization = AppLocalization.of(context); + + return FormCard( + children: [ + DecoratedFormField( + label: localization.feeAmount, + controller: _amountController, + ), + DecoratedFormField( + label: localization.feePercent, + controller: _percentController, + ), + DecoratedFormField( + label: localization.feeCap, + controller: _capController, + ), + ], + ); + } +} diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 989188670..27d644fa7 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -14,6 +14,9 @@ abstract class LocaleCodeAware { mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { + 'fee_amount': 'Fee Amount', + 'fee_percent': 'Fee Percent', + 'fee_cap': 'Fee Cap', 'limits_and_fees': 'Limits/Fees', 'enable_min': 'Enable Min', 'enable_max': 'Enable Max', @@ -14987,6 +14990,11 @@ mixin LocalizationsProvider on LocaleCodeAware { String get limitsAndFees => _localizedValues[localeCode]['limits_and_fees']; + String get feeAmount => _localizedValues[localeCode]['fee_amount']; + + String get feePercent => _localizedValues[localeCode]['fee_percent']; + + String get feeCap => _localizedValues[localeCode]['fee_cap']; String lookup(String key) { final lookupKey = toSnakeCase(key);