@marcos_feitoza/personal-finance-frontend-feature-investments 1.2.1 → 1.2.2
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.2.2](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/compare/v1.2.1...v1.2.2) (2026-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Web responsivo (mobile/tablet/resize) ([f3aa7b2](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/commit/f3aa7b2edd456ca2fe1d32ea3a7f8798dc053fe9))
|
|
7
|
+
|
|
1
8
|
## [1.2.1](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/compare/v1.2.0...v1.2.1) (2026-01-29)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -3,6 +3,7 @@ import 'package:intl/intl.dart';
|
|
|
3
3
|
import 'package:provider/provider.dart';
|
|
4
4
|
import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/utils/app_dialogs.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:personal_finance_frontend_core_ui/widgets/crypto_trade_form.dart';
|
|
8
9
|
import '../viewmodels/crypto_account_viewmodel.dart';
|
|
@@ -119,8 +120,7 @@ class CryptoAccountScreen extends StatelessWidget {
|
|
|
119
120
|
);
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
return
|
|
123
|
-
scrollDirection: Axis.horizontal,
|
|
123
|
+
return ResponsiveHorizontalScroll(
|
|
124
124
|
child: DataTable(
|
|
125
125
|
columnSpacing: 24.0,
|
|
126
126
|
columns: const [
|
|
@@ -205,7 +205,8 @@ class CryptoAccountScreen extends StatelessWidget {
|
|
|
205
205
|
}
|
|
206
206
|
});
|
|
207
207
|
|
|
208
|
-
return
|
|
208
|
+
return ResponsiveHorizontalScroll(
|
|
209
|
+
child: DataTable(
|
|
209
210
|
columns: const [
|
|
210
211
|
DataColumn(label: Text('Date')),
|
|
211
212
|
DataColumn(label: Text('Symbol')),
|
|
@@ -239,6 +240,7 @@ class CryptoAccountScreen extends StatelessWidget {
|
|
|
239
240
|
),
|
|
240
241
|
]);
|
|
241
242
|
}).toList(),
|
|
243
|
+
),
|
|
242
244
|
);
|
|
243
245
|
}
|
|
244
246
|
|
|
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
|
|
4
4
|
import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/utils/app_dialogs.dart';
|
|
6
6
|
import 'package:personal_finance_frontend_core_ui/utils/app_snackbars.dart';
|
|
7
|
+
import 'package:personal_finance_frontend_core_ui/utils/app_responsive.dart';
|
|
7
8
|
import 'package:personal_finance_frontend_core_ui/widgets/trade_form.dart';
|
|
8
9
|
import 'package:personal_finance_frontend_core_ui/widgets/dividend_log_form.dart';
|
|
9
10
|
import 'package:personal_finance_frontend_core_ui/widgets/app_widgets.dart';
|
|
@@ -183,8 +184,7 @@ class InvestmentAccountScreen extends StatelessWidget {
|
|
|
183
184
|
);
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
return
|
|
187
|
-
scrollDirection: Axis.horizontal,
|
|
187
|
+
return ResponsiveHorizontalScroll(
|
|
188
188
|
child: DataTable(
|
|
189
189
|
columnSpacing: 24.0,
|
|
190
190
|
columns: [
|
|
@@ -264,48 +264,57 @@ class InvestmentAccountScreen extends StatelessWidget {
|
|
|
264
264
|
);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
return
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
267
|
+
return ResponsiveHorizontalScroll(
|
|
268
|
+
child: DataTable(
|
|
269
|
+
columns: const [
|
|
270
|
+
DataColumn(label: Text('Date')),
|
|
271
|
+
DataColumn(label: Text('Trade Age')),
|
|
272
|
+
DataColumn(label: Text('Symbol')),
|
|
273
|
+
DataColumn(label: Text('Type')),
|
|
274
|
+
DataColumn(label: Text('Shares')),
|
|
275
|
+
DataColumn(label: Text('Price')),
|
|
276
|
+
DataColumn(label: Text('Total')),
|
|
277
|
+
DataColumn(label: Text('Actions')),
|
|
278
|
+
],
|
|
279
|
+
rows: filteredHistory.map((item) {
|
|
280
|
+
final isTrade = item['history_type'] == 'trade';
|
|
281
|
+
// final isDividend = item['history_type'] == 'dividend'; // Reserved for future use.
|
|
281
282
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
283
|
+
final tradeDate = DateTime.parse(item['date'] as String);
|
|
284
|
+
final tradeAge = DateTime.now().difference(tradeDate);
|
|
285
|
+
final symbol = item['symbol'] as String? ?? 'N/A';
|
|
286
|
+
final type = item['type'] as String? ?? 'N/A';
|
|
287
|
+
final int id = item['id'] as int;
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
final double shares = isTrade
|
|
290
|
+
? (double.tryParse(item['shares']?.toString() ?? '0.0') ?? 0.0)
|
|
291
|
+
: 0.0;
|
|
292
|
+
final double price = isTrade
|
|
293
|
+
? (double.tryParse(item['price']?.toString() ?? '0.0') ?? 0.0)
|
|
294
|
+
: 0.0;
|
|
295
|
+
final double total = isTrade
|
|
296
|
+
? (shares * price)
|
|
297
|
+
: (double.tryParse(item['total']?.toString() ?? '0.0') ?? 0.0);
|
|
291
298
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
299
|
+
return DataRow(cells: [
|
|
300
|
+
DataCell(Text(DateFormat('yyyy-MM-dd').format(tradeDate))),
|
|
301
|
+
DataCell(Text(_formatDuration(tradeAge))),
|
|
302
|
+
DataCell(Text(symbol)),
|
|
303
|
+
DataCell(Text(type)),
|
|
304
|
+
DataCell(isTrade ? Text(shares.toStringAsFixed(4)) : const Text('-')),
|
|
305
|
+
DataCell(isTrade ? Text(_formatCurrency(price)) : const Text('-')),
|
|
306
|
+
DataCell(Text(_formatCurrency(total))),
|
|
307
|
+
DataCell(
|
|
308
|
+
IconButton(
|
|
309
|
+
icon: const Icon(Icons.delete, color: Colors.red),
|
|
310
|
+
onPressed: () =>
|
|
311
|
+
_confirmAndDeleteItem(context, viewModel, id, isTrade),
|
|
312
|
+
tooltip: 'Delete Item',
|
|
313
|
+
),
|
|
305
314
|
),
|
|
306
|
-
)
|
|
307
|
-
|
|
308
|
-
|
|
315
|
+
]);
|
|
316
|
+
}).toList(),
|
|
317
|
+
),
|
|
309
318
|
);
|
|
310
319
|
}
|
|
311
320
|
|
|
@@ -3,6 +3,7 @@ import 'package:intl/intl.dart';
|
|
|
3
3
|
import 'package:provider/provider.dart';
|
|
4
4
|
import 'package:personal_finance_frontend_core_services/providers/auth_provider.dart';
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/utils/app_dialogs.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:personal_finance_frontend_core_ui/widgets/rrsp_contribution_form.dart';
|
|
8
9
|
import '../viewmodels/rrsp_sun_life_viewmodel.dart';
|
|
@@ -100,8 +101,9 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
100
101
|
final double unrealizedPL = double.tryParse(summary['unrealized_pl']?.toString() ?? '0.0') ?? 0.0;
|
|
101
102
|
final plColor = (unrealizedPL >= 0) ? Colors.green : Colors.red;
|
|
102
103
|
|
|
103
|
-
return
|
|
104
|
-
|
|
104
|
+
return ResponsiveHorizontalScroll(
|
|
105
|
+
child: DataTable(
|
|
106
|
+
columns: const [
|
|
105
107
|
DataColumn(label: Text('User Contr.')),
|
|
106
108
|
DataColumn(label: Text('Company Contr.')),
|
|
107
109
|
DataColumn(label: Text('Total Contributed')),
|
|
@@ -110,7 +112,7 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
110
112
|
DataColumn(label: Text('Market Value')),
|
|
111
113
|
DataColumn(label: Text('Portfolio %')),
|
|
112
114
|
],
|
|
113
|
-
|
|
115
|
+
rows: [
|
|
114
116
|
DataRow(
|
|
115
117
|
cells: [
|
|
116
118
|
DataCell(
|
|
@@ -133,7 +135,8 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
133
135
|
),
|
|
134
136
|
],
|
|
135
137
|
),
|
|
136
|
-
|
|
138
|
+
],
|
|
139
|
+
),
|
|
137
140
|
);
|
|
138
141
|
}
|
|
139
142
|
|
|
@@ -148,8 +151,9 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
148
151
|
);
|
|
149
152
|
}
|
|
150
153
|
|
|
151
|
-
return
|
|
152
|
-
|
|
154
|
+
return ResponsiveHorizontalScroll(
|
|
155
|
+
child: DataTable(
|
|
156
|
+
columns: const [
|
|
153
157
|
DataColumn(label: Text('Date')),
|
|
154
158
|
DataColumn(label: Text('User Contr.')),
|
|
155
159
|
DataColumn(label: Text('Company Contr.')),
|
|
@@ -160,7 +164,7 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
160
164
|
DataColumn(label: Text('Portfolio %')),
|
|
161
165
|
DataColumn(label: Text('Actions')),
|
|
162
166
|
],
|
|
163
|
-
|
|
167
|
+
rows: viewModel.contributions.map((c) {
|
|
164
168
|
final contributionId = c['id'] as int;
|
|
165
169
|
final rrspAmount = double.tryParse(c['rrsp_amount']?.toString() ?? '0.0') ?? 0.0;
|
|
166
170
|
final dpspAmount = double.tryParse(c['dpsp_amount']?.toString() ?? '0.0') ?? 0.0;
|
|
@@ -207,7 +211,8 @@ class RrspSunLifeScreen extends StatelessWidget {
|
|
|
207
211
|
),
|
|
208
212
|
],
|
|
209
213
|
);
|
|
210
|
-
|
|
214
|
+
}).toList(),
|
|
215
|
+
),
|
|
211
216
|
);
|
|
212
217
|
}
|
|
213
218
|
|