@marcos_feitoza/personal-finance-frontend-feature-management 1.0.2 → 1.0.4

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,17 @@
1
+ ## [1.0.4](https://github.com/MarcosOps/personal-finance-frontend-feature-management/compare/v1.0.3...v1.0.4) (2026-01-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Padronizar mensagens de erro e estados de loading ([039757d](https://github.com/MarcosOps/personal-finance-frontend-feature-management/commit/039757d6c16a0f521aad7a653cd4b907eef94177))
7
+
8
+ ## [1.0.3](https://github.com/MarcosOps/personal-finance-frontend-feature-management/compare/v1.0.2...v1.0.3) (2026-01-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Web responsivo (mobile/tablet/resize) ([f8b2be9](https://github.com/MarcosOps/personal-finance-frontend-feature-management/commit/f8b2be9a6b9b6fbe3b5a0bd8fed602204142461d))
14
+
1
15
  ## [1.0.2](https://github.com/MarcosOps/personal-finance-frontend-feature-management/compare/v1.0.1...v1.0.2) (2026-01-29)
2
16
 
3
17
 
@@ -4,6 +4,8 @@ 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/widgets/app_async_state_view.dart';
8
+ import 'package:personal_finance_frontend_core_ui/utils/app_responsive.dart';
7
9
  import 'package:personal_finance_frontend_core_services/models/payment_method.dart';
8
10
  import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
9
11
 
@@ -60,83 +62,94 @@ class ManageTransactionsScreen extends StatelessWidget {
60
62
  ),
61
63
  body: Consumer<ManageTransactionsViewModel>(
62
64
  builder: (context, viewModel, child) {
63
- if (viewModel.isLoading) {
64
- return const Center(child: CircularProgressIndicator());
65
- }
66
- if (viewModel.errorMessage.isNotEmpty) {
67
- return Center(child: Text(viewModel.errorMessage));
68
- }
69
- return Column(
70
- children: [
71
- _buildFilters(context, viewModel),
72
- Expanded(
73
- child: SingleChildScrollView(
74
- child: DataTable(
75
- columns: const [
76
- DataColumn(label: Text('Select')),
77
- DataColumn(label: Text('Date')),
78
- DataColumn(label: Text('Category')),
79
- DataColumn(label: Text('Subcategory')),
80
- DataColumn(label: Text('Method')),
81
- DataColumn(label: Text('Amount')),
82
- DataColumn(label: Text('Description')),
83
- DataColumn(label: Text('Paid')), // Added Paid column
84
- DataColumn(label: Text('Actions')),
85
- ],
86
- rows: viewModel.transactions.map((transaction) {
87
- return DataRow(
88
- selected: viewModel.selectedTransactionIds
89
- .contains(transaction.id),
90
- onSelectChanged: (isSelected) {
91
- viewModel
92
- .toggleTransactionSelection(transaction.id);
93
- },
94
- cells: [
95
- DataCell(Checkbox(
96
- value: viewModel.selectedTransactionIds
97
- .contains(transaction.id),
98
- onChanged: (isSelected) {
99
- viewModel
100
- .toggleTransactionSelection(transaction.id);
101
- },
102
- )),
103
- DataCell(Text(DateFormat('yyyy-MM-dd')
104
- .format(transaction.date))),
105
- DataCell(Text(transaction.category)),
106
- DataCell(Text(transaction.subcategory)),
107
- DataCell(Text(transaction.paymentMethod)),
108
- DataCell(Text(NumberFormat.currency(
109
- locale: 'en_CA', symbol: '\$')
110
- .format(transaction.amount))),
111
- DataCell(Text(transaction.description)),
112
- DataCell(Switch( // Added Switch for Paid status
113
- value: transaction.isPaid,
114
- onChanged: (bool newValue) {
115
- print('Switch onChanged: transaction.id=${transaction.id}, newValue=$newValue'); // Added log
116
- viewModel.updateTransactionPaidStatus(transaction.id, newValue);
117
- },
118
- )),
119
- DataCell(IconButton(
120
- icon: const Icon(Icons.edit),
121
- onPressed: () {
122
- showDialog(
123
- context: context,
124
- builder: (BuildContext context) {
125
- return EditTransactionDialog(
126
- transaction: transaction,
127
- viewModel: viewModel,
128
- );
129
- },
130
- );
131
- },
132
- )),
133
- ],
134
- );
135
- }).toList(),
136
- ),
65
+ return AppAsyncStateView(
66
+ isLoading: viewModel.isLoading,
67
+ errorMessage:
68
+ viewModel.errorMessage.isEmpty ? null : viewModel.errorMessage,
69
+ onRetry: viewModel.fetchTransactions,
70
+ child: Column(
71
+ children: [
72
+ _buildFilters(context, viewModel),
73
+ Expanded(
74
+ child: viewModel.transactions.isEmpty
75
+ ? const Center(
76
+ child: Padding(
77
+ padding: EdgeInsets.all(16.0),
78
+ child: Text(
79
+ 'No transactions found for the selected filters.',
80
+ ),
81
+ ),
82
+ )
83
+ : SingleChildScrollView(
84
+ child: ResponsiveHorizontalScroll(
85
+ child: DataTable(
86
+ columns: const [
87
+ DataColumn(label: Text('Select')),
88
+ DataColumn(label: Text('Date')),
89
+ DataColumn(label: Text('Category')),
90
+ DataColumn(label: Text('Subcategory')),
91
+ DataColumn(label: Text('Method')),
92
+ DataColumn(label: Text('Amount')),
93
+ DataColumn(label: Text('Description')),
94
+ DataColumn(label: Text('Paid')),
95
+ DataColumn(label: Text('Actions')),
96
+ ],
97
+ rows: viewModel.transactions.map((transaction) {
98
+ return DataRow(
99
+ selected: viewModel.selectedTransactionIds
100
+ .contains(transaction.id),
101
+ onSelectChanged: (isSelected) {
102
+ viewModel.toggleTransactionSelection(
103
+ transaction.id);
104
+ },
105
+ cells: [
106
+ DataCell(Checkbox(
107
+ value: viewModel.selectedTransactionIds
108
+ .contains(transaction.id),
109
+ onChanged: (isSelected) {
110
+ viewModel.toggleTransactionSelection(
111
+ transaction.id);
112
+ },
113
+ )),
114
+ DataCell(Text(DateFormat('yyyy-MM-dd')
115
+ .format(transaction.date))),
116
+ DataCell(Text(transaction.category)),
117
+ DataCell(Text(transaction.subcategory)),
118
+ DataCell(Text(transaction.paymentMethod)),
119
+ DataCell(Text(NumberFormat.currency(
120
+ locale: 'en_CA', symbol: '\$')
121
+ .format(transaction.amount))),
122
+ DataCell(Text(transaction.description)),
123
+ DataCell(Switch(
124
+ value: transaction.isPaid,
125
+ onChanged: (bool newValue) {
126
+ viewModel.updateTransactionPaidStatus(
127
+ transaction.id, newValue);
128
+ },
129
+ )),
130
+ DataCell(IconButton(
131
+ icon: const Icon(Icons.edit),
132
+ onPressed: () {
133
+ showDialog(
134
+ context: context,
135
+ builder: (BuildContext context) {
136
+ return EditTransactionDialog(
137
+ transaction: transaction,
138
+ viewModel: viewModel,
139
+ );
140
+ },
141
+ );
142
+ },
143
+ )),
144
+ ],
145
+ );
146
+ }).toList(),
147
+ ),
148
+ ),
149
+ ),
137
150
  ),
138
- ),
139
- ],
151
+ ],
152
+ ),
140
153
  );
141
154
  },
142
155
  ),
@@ -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: DataTable(
181
- columns: const [
182
- DataColumn(label: Text('Select')),
183
- DataColumn(label: Text('Date')),
184
- DataColumn(label: Text('Subcategory')),
185
- DataColumn(label: Text('Method')),
186
- DataColumn(label: Text('Amount')),
187
- ],
188
- rows: _unpaidTransactions.map((transaction) {
189
- final transactionId = transaction['id'] as int;
190
- final double amount = double.tryParse(
191
- transaction['amount']?.toString() ??
192
- '0.0') ??
193
- 0.0;
194
- return DataRow(
195
- cells: [
196
- DataCell(Checkbox(
197
- value: _selectedIds.contains(transactionId),
198
- onChanged: _selectedPaymentMethod == null
199
- ? null
200
- : (bool? selected) {
201
- _onTransactionSelected(
202
- selected, transaction);
203
- },
204
- )),
205
- DataCell(Text(DateFormat('yyyy-MM-dd').format(
206
- DateTime.parse(transaction['date'])))),
207
- DataCell(Text(transaction['subcategory'] ??
208
- 'No subcategory')),
209
- DataCell(Text(
210
- transaction['payment_method'] ?? 'N/A')),
211
- DataCell(Text(
212
- '${_formatCurrency(amount)}',
213
- style: TextStyle(
214
- color: transaction['type'] == 'debit'
215
- ? Colors.red
216
- : Colors.green,
217
- fontWeight: FontWeight.bold,
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
- }).toList(),
232
+ ],
233
+ );
234
+ }).toList(),
235
+ ),
223
236
  ),
224
237
  ),
225
238
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marcos_feitoza/personal-finance-frontend-feature-management",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },