@marcos_feitoza/personal-finance-frontend-feature-management 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.0.3](https://github.com/MarcosOps/personal-finance-frontend-feature-management/compare/v1.0.2...v1.0.3) (2026-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Web responsivo (mobile/tablet/resize) ([f8b2be9](https://github.com/MarcosOps/personal-finance-frontend-feature-management/commit/f8b2be9a6b9b6fbe3b5a0bd8fed602204142461d))
|
|
7
|
+
|
|
1
8
|
## [1.0.2](https://github.com/MarcosOps/personal-finance-frontend-feature-management/compare/v1.0.1...v1.0.2) (2026-01-29)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
|
|
4
4
|
import '../viewmodels/manage_transactions_viewmodel.dart';
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/widgets/edit_transaction_dialog.dart';
|
|
6
6
|
import 'package:personal_finance_frontend_core_ui/widgets/app_widgets.dart';
|
|
7
|
+
import 'package:personal_finance_frontend_core_ui/utils/app_responsive.dart';
|
|
7
8
|
import 'package:personal_finance_frontend_core_services/models/payment_method.dart';
|
|
8
9
|
import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
|
|
9
10
|
|
|
@@ -71,68 +72,70 @@ class ManageTransactionsScreen extends StatelessWidget {
|
|
|
71
72
|
_buildFilters(context, viewModel),
|
|
72
73
|
Expanded(
|
|
73
74
|
child: SingleChildScrollView(
|
|
74
|
-
child:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
75
|
+
child: ResponsiveHorizontalScroll(
|
|
76
|
+
child: DataTable(
|
|
77
|
+
columns: const [
|
|
78
|
+
DataColumn(label: Text('Select')),
|
|
79
|
+
DataColumn(label: Text('Date')),
|
|
80
|
+
DataColumn(label: Text('Category')),
|
|
81
|
+
DataColumn(label: Text('Subcategory')),
|
|
82
|
+
DataColumn(label: Text('Method')),
|
|
83
|
+
DataColumn(label: Text('Amount')),
|
|
84
|
+
DataColumn(label: Text('Description')),
|
|
85
|
+
DataColumn(label: Text('Paid')), // Added Paid column
|
|
86
|
+
DataColumn(label: Text('Actions')),
|
|
87
|
+
],
|
|
88
|
+
rows: viewModel.transactions.map((transaction) {
|
|
89
|
+
return DataRow(
|
|
90
|
+
selected: viewModel.selectedTransactionIds
|
|
91
|
+
.contains(transaction.id),
|
|
92
|
+
onSelectChanged: (isSelected) {
|
|
93
|
+
viewModel
|
|
94
|
+
.toggleTransactionSelection(transaction.id);
|
|
95
|
+
},
|
|
96
|
+
cells: [
|
|
97
|
+
DataCell(Checkbox(
|
|
98
|
+
value: viewModel.selectedTransactionIds
|
|
99
|
+
.contains(transaction.id),
|
|
100
|
+
onChanged: (isSelected) {
|
|
101
|
+
viewModel
|
|
102
|
+
.toggleTransactionSelection(transaction.id);
|
|
103
|
+
},
|
|
104
|
+
)),
|
|
105
|
+
DataCell(Text(DateFormat('yyyy-MM-dd')
|
|
106
|
+
.format(transaction.date))),
|
|
107
|
+
DataCell(Text(transaction.category)),
|
|
108
|
+
DataCell(Text(transaction.subcategory)),
|
|
109
|
+
DataCell(Text(transaction.paymentMethod)),
|
|
110
|
+
DataCell(Text(NumberFormat.currency(
|
|
111
|
+
locale: 'en_CA', symbol: '\$')
|
|
112
|
+
.format(transaction.amount))),
|
|
113
|
+
DataCell(Text(transaction.description)),
|
|
114
|
+
DataCell(Switch( // Added Switch for Paid status
|
|
115
|
+
value: transaction.isPaid,
|
|
116
|
+
onChanged: (bool newValue) {
|
|
117
|
+
print('Switch onChanged: transaction.id=${transaction.id}, newValue=$newValue'); // Added log
|
|
118
|
+
viewModel.updateTransactionPaidStatus(transaction.id, newValue);
|
|
119
|
+
},
|
|
120
|
+
)),
|
|
121
|
+
DataCell(IconButton(
|
|
122
|
+
icon: const Icon(Icons.edit),
|
|
123
|
+
onPressed: () {
|
|
124
|
+
showDialog(
|
|
125
|
+
context: context,
|
|
126
|
+
builder: (BuildContext context) {
|
|
127
|
+
return EditTransactionDialog(
|
|
128
|
+
transaction: transaction,
|
|
129
|
+
viewModel: viewModel,
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
},
|
|
134
|
+
)),
|
|
135
|
+
],
|
|
136
|
+
);
|
|
137
|
+
}).toList(),
|
|
138
|
+
),
|
|
136
139
|
),
|
|
137
140
|
),
|
|
138
141
|
),
|
|
@@ -3,6 +3,7 @@ import 'package:personal_finance_frontend_core_services/services/transaction_ser
|
|
|
3
3
|
import 'package:intl/intl.dart';
|
|
4
4
|
import 'package:personal_finance_frontend_core_services/models/payment_method.dart';
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/widgets/app_widgets.dart';
|
|
6
|
+
import 'package:personal_finance_frontend_core_ui/utils/app_responsive.dart';
|
|
6
7
|
import 'package:personal_finance_frontend_core_ui/utils/app_snackbars.dart';
|
|
7
8
|
import 'package:provider/provider.dart';
|
|
8
9
|
import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
|
|
@@ -149,7 +150,7 @@ class _ReconciliationScreenState extends State<ReconciliationScreen> {
|
|
|
149
150
|
Widget build(BuildContext context) {
|
|
150
151
|
return Scaffold(
|
|
151
152
|
appBar: AppBar(
|
|
152
|
-
title: Text('Reconcile Transactions'),
|
|
153
|
+
title: const Text('Reconcile Transactions'),
|
|
153
154
|
actions: [
|
|
154
155
|
Center(
|
|
155
156
|
child: Padding(
|
|
@@ -177,49 +178,61 @@ class _ReconciliationScreenState extends State<ReconciliationScreen> {
|
|
|
177
178
|
? const Center(child: Text('No unpaid transactions found.'))
|
|
178
179
|
: SingleChildScrollView(
|
|
179
180
|
scrollDirection: Axis.vertical,
|
|
180
|
-
child:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
181
|
+
child: ResponsiveHorizontalScroll(
|
|
182
|
+
child: DataTable(
|
|
183
|
+
columns: const [
|
|
184
|
+
DataColumn(label: Text('Select')),
|
|
185
|
+
DataColumn(label: Text('Date')),
|
|
186
|
+
DataColumn(label: Text('Subcategory')),
|
|
187
|
+
DataColumn(label: Text('Method')),
|
|
188
|
+
DataColumn(label: Text('Amount')),
|
|
189
|
+
],
|
|
190
|
+
rows: _unpaidTransactions.map((transaction) {
|
|
191
|
+
final transactionId = transaction['id'] as int;
|
|
192
|
+
final double amount = double.tryParse(
|
|
193
|
+
transaction['amount']?.toString() ?? '0.0') ??
|
|
194
|
+
0.0;
|
|
195
|
+
|
|
196
|
+
return DataRow(
|
|
197
|
+
cells: [
|
|
198
|
+
DataCell(
|
|
199
|
+
Checkbox(
|
|
200
|
+
value: _selectedIds.contains(transactionId),
|
|
201
|
+
onChanged: _selectedPaymentMethod == null
|
|
202
|
+
? null
|
|
203
|
+
: (bool? selected) {
|
|
204
|
+
_onTransactionSelected(selected, transaction);
|
|
205
|
+
},
|
|
206
|
+
),
|
|
207
|
+
),
|
|
208
|
+
DataCell(
|
|
209
|
+
Text(
|
|
210
|
+
DateFormat('yyyy-MM-dd').format(
|
|
211
|
+
DateTime.parse(transaction['date']),
|
|
212
|
+
),
|
|
213
|
+
),
|
|
214
|
+
),
|
|
215
|
+
DataCell(
|
|
216
|
+
Text(transaction['subcategory'] ?? 'No subcategory'),
|
|
217
|
+
),
|
|
218
|
+
DataCell(
|
|
219
|
+
Text(transaction['payment_method'] ?? 'N/A'),
|
|
220
|
+
),
|
|
221
|
+
DataCell(
|
|
222
|
+
Text(
|
|
223
|
+
_formatCurrency(amount),
|
|
224
|
+
style: TextStyle(
|
|
225
|
+
color: transaction['type'] == 'debit'
|
|
226
|
+
? Colors.red
|
|
227
|
+
: Colors.green,
|
|
228
|
+
fontWeight: FontWeight.bold,
|
|
229
|
+
),
|
|
230
|
+
),
|
|
218
231
|
),
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
)
|
|
222
|
-
|
|
232
|
+
],
|
|
233
|
+
);
|
|
234
|
+
}).toList(),
|
|
235
|
+
),
|
|
223
236
|
),
|
|
224
237
|
),
|
|
225
238
|
),
|