feat(App): update Finlytic Flutter app UI and blocs

This commit is contained in:
2026-08-09 21:01:46 +02:00
parent e7427b7464
commit a708d2977c
591 changed files with 1095105 additions and 0 deletions
@@ -0,0 +1,145 @@
import 'package:finlytic_app/core/network/api_client.dart';
import 'package:finlytic_app/features/asset_detail/models/asset_model.dart';
import 'package:finlytic_app/features/asset_detail/models/fundamental_data_model.dart';
import 'package:finlytic_app/features/asset_detail/models/technical_analysis_model.dart';
import 'package:finlytic_app/features/asset_detail/models/manual_analysis_request_dto.dart';
import 'package:finlytic_app/features/trades/models/trade_model.dart';
import 'package:finlytic_app/features/trades/models/trade_acceptance_dto.dart';
class AssetRepository {
final ApiClient apiClient;
AssetRepository({required this.apiClient});
Future<void> forceRefreshFundamentalData(String symbol) async {
try {
await apiClient.post('/api/v1/assets/$symbol/refresh');
} catch (e) {
print('Error forcing refresh: $e');
}
}
Future<FundamentalDataModel?> getFundamentalData(String symbol) async {
try {
final res = await apiClient.get('/api/v1/assets/fundamentals/$symbol');
if (res.statusCode == 200 && res.data != null) {
return FundamentalDataModel.fromJson(res.data);
}
} catch (e) {
print('Error fetching fundamentals for $symbol: $e');
}
return null;
}
Future<TechnicalAnalysisModel?> getTechnicalAnalysis(String symbol) async {
try {
final res = await apiClient.get('/api/v1/ta/$symbol');
if (res.statusCode == 200 && res.data != null) {
return TechnicalAnalysisModel.fromJson(res.data);
}
} catch (e) {
print('Error fetching TA for $symbol: $e');
}
return null;
}
Future<AssetModel?> getAssetHeader(String isin, {String? exchange, String? ticker}) async {
try {
String url = '/api/v1/assets/header/$isin?';
if (ticker != null && ticker.isNotEmpty) {
url += 'ticker=$ticker';
}
final res = await apiClient.get(url);
if (res.statusCode == 200 && res.data != null) {
return AssetModel.fromJson(res.data);
}
} catch (e) {
print('Error fetching asset header for $isin: $e');
}
return null;
}
Future<FundamentalDataModel?> getAssetFundamentals(String isin, bool forceRefresh, {String? ticker}) async {
try {
String url = '/api/v1/assets/fundamentals/$isin?forceRefresh=$forceRefresh';
if (ticker != null && ticker.isNotEmpty) {
url += '&ticker=$ticker';
}
final res = await apiClient.get(url);
if (res.statusCode == 200 && res.data != null) {
return FundamentalDataModel.fromJson(res.data);
}
} catch (e) {
print('Error fetching fundamentals for $isin: $e');
}
return null;
}
Future<TechnicalAnalysisModel?> getAssetTechnical(String isin, bool forceRefresh, {String? ticker}) async {
try {
String url = '/api/v1/ta/$isin?forceRefresh=$forceRefresh';
if (ticker != null && ticker.isNotEmpty) {
url += '&ticker=$ticker';
}
final res = await apiClient.get(url);
if (res.statusCode == 200 && res.data != null) {
return TechnicalAnalysisModel.fromJson(res.data);
}
} catch (e) {
print('Error fetching TA for $isin: $e');
}
return null;
}
Future<List<TradeModel>> getAssetTrades(String isin, String? status) async {
try {
String url = '/api/v1/trades?isin=$isin';
if (status != null) url += '&status=$status';
final res = await apiClient.get(url);
if (res.statusCode == 200 && res.data != null) {
final List<dynamic> list = res.data;
return list.map((json) => TradeModel.fromJson(json)).toList();
}
} catch (e) {
print('Error fetching trades for $isin: $e');
}
return [];
}
Future<void> triggerManualAnalysis(String isin, {ManualAnalysisRequestDto? payload}) async {
try {
final body = payload != null ? payload.toJson() : {'isin': isin};
await apiClient.post('/api/v1/analyze/manual', data: body);
} catch (e) {
print('Error triggering manual analysis for $isin: $e');
throw e;
}
}
Future<void> rejectTrade(String tradeId) async {
try {
await apiClient.post('/api/v1/user/trades/$tradeId/reject');
} catch (e) {
print('Error rejecting trade $tradeId: $e');
throw e;
}
}
Future<void> acceptTrade(TradeAcceptanceDto tradeAcceptanceDto) async {
try {
final payload = tradeAcceptanceDto.toJson();
await apiClient.post('/api/v1/user/trades/accept', data: payload);
} catch (e) {
print('Error accepting trade: $e');
throw e;
}
}
Future<void> closeTrade(String tradeId, double exitPrice) async {
try {
await apiClient.post('/api/v1/user/trades/$tradeId/close', data: {'userExitPrice': exitPrice});
} catch (e) {
print('Error closing trade $tradeId: $e');
throw e;
}
}
}