@marcos_feitoza/personal-finance-frontend-feature-investments 1.2.2 → 1.2.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.2.3](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/compare/v1.2.2...v1.2.3) (2026-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Padronizar mensagens de erro e estados de loading ([3562e80](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/commit/3562e80f02f1829fbb8702637c97abd9e879ca1a))
|
|
7
|
+
|
|
1
8
|
## [1.2.2](https://github.com/MarcosOps/personal-finance-frontend-feature-investments/compare/v1.2.1...v1.2.2) (2026-01-30)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -5,6 +5,7 @@ import 'package:personal_finance_frontend_core_services/providers/auth_provider.
|
|
|
5
5
|
import 'package:personal_finance_frontend_core_ui/utils/app_dialogs.dart';
|
|
6
6
|
import 'package:personal_finance_frontend_core_ui/utils/app_responsive.dart';
|
|
7
7
|
import 'package:personal_finance_frontend_core_ui/utils/app_snackbars.dart';
|
|
8
|
+
import 'package:personal_finance_frontend_core_ui/widgets/app_async_state_view.dart';
|
|
8
9
|
import 'package:personal_finance_frontend_core_ui/widgets/crypto_trade_form.dart';
|
|
9
10
|
import '../viewmodels/crypto_account_viewmodel.dart';
|
|
10
11
|
|
|
@@ -56,45 +57,60 @@ class CryptoAccountScreen extends StatelessWidget {
|
|
|
56
57
|
),
|
|
57
58
|
],
|
|
58
59
|
),
|
|
60
|
+
// NOTE: Don't treat "no trades yet" as a full-screen empty state,
|
|
61
|
+
// otherwise the trade form disappears for new users.
|
|
62
|
+
// Empty states are handled inside the sections (tables).
|
|
59
63
|
body: viewModel.isLoading
|
|
60
|
-
? const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
64
|
+
? const AppAsyncStateView(
|
|
65
|
+
isLoading: true,
|
|
66
|
+
child: SizedBox.shrink(),
|
|
67
|
+
)
|
|
68
|
+
: AppAsyncStateView(
|
|
69
|
+
isLoading: false,
|
|
70
|
+
errorMessage: viewModel.errorMessage,
|
|
71
|
+
onRetry: viewModel.fetchData,
|
|
72
|
+
child: RefreshIndicator(
|
|
73
|
+
onRefresh: viewModel.fetchData,
|
|
74
|
+
child: SingleChildScrollView(
|
|
75
|
+
physics: const AlwaysScrollableScrollPhysics(),
|
|
76
|
+
padding: const EdgeInsets.all(16.0),
|
|
77
|
+
child: Column(
|
|
78
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
79
|
+
children: [
|
|
80
|
+
Row(
|
|
81
|
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
82
|
+
children: [
|
|
83
|
+
Text(
|
|
84
|
+
'Portfolio Summary',
|
|
85
|
+
style: Theme.of(context).textTheme.titleLarge,
|
|
81
86
|
),
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
87
|
+
if (viewModel.isFetchingPrices)
|
|
88
|
+
const SizedBox(
|
|
89
|
+
height: 20,
|
|
90
|
+
width: 20,
|
|
91
|
+
child: CircularProgressIndicator(
|
|
92
|
+
strokeWidth: 2.0,
|
|
93
|
+
),
|
|
94
|
+
),
|
|
95
|
+
],
|
|
96
|
+
),
|
|
97
|
+
_buildSinteticoTable(context, viewModel),
|
|
98
|
+
const SizedBox(height: 24),
|
|
99
|
+
CryptoTradeForm(
|
|
100
|
+
accountName: accountName,
|
|
101
|
+
portfolioSummary: viewModel.portfolioSummary,
|
|
102
|
+
onTradeCreated: (_) => viewModel.fetchData(),
|
|
103
|
+
token: viewModel.token,
|
|
104
|
+
),
|
|
105
|
+
const SizedBox(height: 24),
|
|
106
|
+
Text(
|
|
107
|
+
'Trade History',
|
|
108
|
+
style: Theme.of(context).textTheme.titleLarge,
|
|
109
|
+
),
|
|
110
|
+
const SizedBox(height: 8),
|
|
111
|
+
_buildAnaliticoTable(context, viewModel),
|
|
112
|
+
],
|
|
113
|
+
),
|
|
98
114
|
),
|
|
99
115
|
),
|
|
100
116
|
),
|
|
@@ -18,6 +18,8 @@ class CryptoAccountViewModel extends ChangeNotifier {
|
|
|
18
18
|
bool _isLoading = true;
|
|
19
19
|
bool _isFetchingPrices = false;
|
|
20
20
|
|
|
21
|
+
String? _errorMessage;
|
|
22
|
+
|
|
21
23
|
// Getters
|
|
22
24
|
List<Map<String, dynamic>> get trades => _trades;
|
|
23
25
|
List<Map<String, dynamic>> get assets => _assets;
|
|
@@ -27,6 +29,7 @@ class CryptoAccountViewModel extends ChangeNotifier {
|
|
|
27
29
|
double get accountTotalValue => _accountTotalValue;
|
|
28
30
|
bool get isLoading => _isLoading;
|
|
29
31
|
bool get isFetchingPrices => _isFetchingPrices;
|
|
32
|
+
String? get errorMessage => _errorMessage;
|
|
30
33
|
String? get token => _token;
|
|
31
34
|
|
|
32
35
|
CryptoAccountViewModel({required this.accountName, required String? token}) {
|
|
@@ -42,6 +45,7 @@ class CryptoAccountViewModel extends ChangeNotifier {
|
|
|
42
45
|
Future<void> fetchData() async {
|
|
43
46
|
if (_token == null) return;
|
|
44
47
|
_isLoading = true;
|
|
48
|
+
_errorMessage = null;
|
|
45
49
|
notifyListeners();
|
|
46
50
|
|
|
47
51
|
try {
|
|
@@ -63,7 +67,8 @@ class CryptoAccountViewModel extends ChangeNotifier {
|
|
|
63
67
|
await _fetchLivePrices();
|
|
64
68
|
|
|
65
69
|
} catch (e) {
|
|
66
|
-
|
|
70
|
+
_errorMessage = 'Failed to load account data: $e';
|
|
71
|
+
debugPrint('[CryptoAccountViewModel] fetchData failed: $e');
|
|
67
72
|
} finally {
|
|
68
73
|
_isLoading = false;
|
|
69
74
|
notifyListeners();
|