dev
dart 134 lines 4.57 KB
Raw
1 import 'package:cake_wallet/cake_pay/src/models/cake_pay_card.dart';
2 import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart';
3 import 'package:flutter/material.dart';
4
5 import 'enter_amount_widget.dart';
6
7 class PrepaidRangeAmountWidget extends StatefulWidget {
8 const PrepaidRangeAmountWidget({
9 required this.fiatCurrency,
10 required this.prepaidRanges,
11 required this.amountFieldFocus,
12 required this.amountController,
13 required this.cakePayBuyCardViewModel,
14 required this.onAmountChanged,
15 });
16
17 final String fiatCurrency;
18 final List<PrepaidRange> prepaidRanges;
19 final FocusNode amountFieldFocus;
20 final TextEditingController amountController;
21 final CakePayBuyCardViewModel cakePayBuyCardViewModel;
22 final Function(String) onAmountChanged;
23
24 @override
25 State<PrepaidRangeAmountWidget> createState() => _PrepaidRangeAmountWidgetState();
26 }
27
28 class _PrepaidRangeAmountWidgetState extends State<PrepaidRangeAmountWidget> {
29 late PrepaidRange _selectedRange;
30
31 @override
32 void initState() {
33 super.initState();
34 _selectedRange = widget.prepaidRanges.first;
35 _applySelectedRange(forceAmountUpdate: widget.amountController.text.isEmpty);
36 }
37
38 @override
39 Widget build(BuildContext context) {
40 return Column(
41 crossAxisAlignment: CrossAxisAlignment.start,
42 children: [
43 Text(
44 'Select range:',
45 style: TextStyle(
46 color: Theme.of(context).textTheme.titleLarge!.color!,
47 fontSize: 16,
48 fontWeight: FontWeight.w600,
49 ),
50 ),
51 const SizedBox(height: 8),
52 DropdownButtonFormField<PrepaidRange>(
53 value: _selectedRange,
54 isExpanded: true,
55 decoration: InputDecoration(
56 contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
57 filled: true,
58 fillColor: Theme.of(context).cardColor,
59 border: OutlineInputBorder(
60 borderRadius: BorderRadius.circular(10),
61 ),
62 enabledBorder: OutlineInputBorder(
63 borderRadius: BorderRadius.circular(10),
64 borderSide: BorderSide(
65 color: Theme.of(context).colorScheme.onSurface.withAlpha(40),
66 ),
67 ),
68 focusedBorder: OutlineInputBorder(
69 borderRadius: BorderRadius.circular(10),
70 borderSide: BorderSide(
71 color: Theme.of(context).colorScheme.primary,
72 ),
73 ),
74 ),
75 items: widget.prepaidRanges
76 .map(
77 (range) => DropdownMenuItem<PrepaidRange>(
78 value: range,
79 child: Text(_rangeLabel(range)),
80 ),
81 )
82 .toList(),
83 onChanged: (range) {
84 if (range == null) return;
85 setState(() => _selectedRange = range);
86 widget.cakePayBuyCardViewModel.onPrepaidRangeChanged(range);
87 _applySelectedRange(forceAmountUpdate: true);
88 },
89 ),
90 const SizedBox(height: 12),
91 EnterAmountWidget(
92 minValue: _formatAmount(_selectedRange.minValue),
93 maxValue: _formatAmount(_selectedRange.maxValue),
94 fiatCurrency: widget.fiatCurrency,
95 amountFieldFocus: widget.amountFieldFocus,
96 amountController: widget.amountController,
97 onAmountChanged: (value) {
98 widget.onAmountChanged(value);
99 widget.cakePayBuyCardViewModel.selectedDenomination = (
100 value.replaceAll(',', '.'),
101 int.tryParse(_selectedRange.rangeId),
102 );
103 },
104 ),
105 ],
106 );
107 }
108
109 void _applySelectedRange({required bool forceAmountUpdate}) {
110 final currentAmount = double.tryParse(widget.amountController.text);
111 final isCurrentAmountInRange = currentAmount != null &&
112 currentAmount >= _selectedRange.minValue &&
113 currentAmount <= _selectedRange.maxValue;
114
115 final nextAmount = forceAmountUpdate || !isCurrentAmountInRange
116 ? _formatAmount(_selectedRange.minValue)
117 : widget.amountController.text;
118
119 widget.amountController.text = nextAmount;
120 widget.onAmountChanged(nextAmount);
121 widget.cakePayBuyCardViewModel.selectedDenomination = (
122 nextAmount.replaceAll(',', '.'),
123 int.tryParse(_selectedRange.rangeId),
124 );
125 }
126
127 String _rangeLabel(PrepaidRange range) {
128 return '${widget.fiatCurrency} ${_formatAmount(range.minValue)} - ${_formatAmount(range.maxValue)}';
129 }
130
131 String _formatAmount(double value) {
132 return value % 1 == 0 ? value.toInt().toString() : value.toStringAsFixed(2);
133 }
134 }