feat(frontend): make baseUrl dynamic for external network access and clear default login inputs

This commit is contained in:
2026-08-16 16:59:36 +02:00
parent aaef272f4e
commit 75a2510b39
7 changed files with 99671 additions and 70616 deletions
+1
View File
@@ -36,4 +36,5 @@ appsettings.Development.json
## Temporary data & scratch ## Temporary data & scratch
Yahoo finance data/ Yahoo finance data/
*.tmp *.tmp
*.tar
FinlyticApp/lib/tickers_grep.json FinlyticApp/lib/tickers_grep.json
+10 -1
View File
@@ -1,4 +1,5 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../services/secure_storage_service.dart'; import '../services/secure_storage_service.dart';
/// Central HTTP ApiClient backed by Dio with automatic 401 Unauthorized handling. /// Central HTTP ApiClient backed by Dio with automatic 401 Unauthorized handling.
@@ -7,7 +8,15 @@ class ApiClient {
late final Dio _dio; late final Dio _dio;
Function()? onUnauthorized; Function()? onUnauthorized;
static const String baseUrl = 'http://localhost:5000'; static String get baseUrl {
if (kIsWeb) {
final origin = Uri.base.origin;
if (origin.isNotEmpty && !origin.contains('null') && !origin.startsWith('file:')) {
return origin;
}
}
return const String.fromEnvironment('BACKEND_URL', defaultValue: 'http://localhost:5000');
}
ApiClient(this._storageService) { ApiClient(this._storageService) {
_dio = Dio( _dio = Dio(
@@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:finlytic_app/core/network/api_client.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:signalr_core/signalr_core.dart'; import 'package:signalr_core/signalr_core.dart';
import '../services/secure_storage_service.dart'; import '../services/secure_storage_service.dart';
@@ -21,7 +22,7 @@ class SignalRService extends ChangeNotifier {
Stream<List<Map<String, dynamic>>> get healthStream => _healthController.stream; Stream<List<Map<String, dynamic>>> get healthStream => _healthController.stream;
Stream<Map<String, dynamic>> get favoritePricesStream => _favoritePricesController.stream; Stream<Map<String, dynamic>> get favoritePricesStream => _favoritePricesController.stream;
static const String baseUrl = 'http://localhost:5000'; static String get baseUrl => ApiClient.baseUrl;
SignalRService(this.storageService); SignalRService(this.storageService);
@@ -14,8 +14,15 @@ class LoginScreen extends StatefulWidget {
class _LoginScreenState extends State<LoginScreen> { class _LoginScreenState extends State<LoginScreen> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController(text: 'admin@finlytic.com'); final _emailController = TextEditingController();
final _passwordController = TextEditingController(text: 'AdminDefaultPassword2026!'); final _passwordController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
void _onLogin() { void _onLogin() {
if (_formKey.currentState?.validate() ?? false) { if (_formKey.currentState?.validate() ?? false) {
@@ -14,19 +14,19 @@ import '../../news/widgets/article_sentiment_dialog.dart';
class DailyNewsSnapshot extends StatelessWidget { class DailyNewsSnapshot extends StatelessWidget {
final ApiClient apiClient; final ApiClient apiClient;
final String backendUrl; final String? backendUrl;
const DailyNewsSnapshot({ const DailyNewsSnapshot({
super.key, super.key,
required this.apiClient, required this.apiClient,
this.backendUrl = 'http://localhost:5000', this.backendUrl,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => NewsBloc( create: (context) => NewsBloc(
repository: NewsRepository(apiClient: apiClient, backendUrl: backendUrl), repository: NewsRepository(apiClient: apiClient, backendUrl: backendUrl ?? ApiClient.baseUrl),
)..add(FetchNews(date: DateTime.now().toIso8601String().substring(0, 10))), )..add(FetchNews(date: DateTime.now().toIso8601String().substring(0, 10))),
child: const _DailyNewsSnapshotContent(), child: const _DailyNewsSnapshotContent(),
); );
+1 -1
View File
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"0cd610717bde95fd88343c64f81c11ba4e5c00
_flutter.loader.load({ _flutter.loader.load({
serviceWorkerSettings: { serviceWorkerSettings: {
serviceWorkerVersion: "2786298959" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */ serviceWorkerVersion: "422571355" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
} }
}); });
File diff suppressed because one or more lines are too long