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,83 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../core/network/api_client.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/widgets/shimmer_loading.dart';
import '../cubit/favorites_cubit.dart';
import '../widgets/watchlist_card.dart';
/// User-bound Watchlist Grid screen with multi-device sync and real-time status.
class FavoritesScreen extends StatelessWidget {
final ApiClient apiClient;
const FavoritesScreen({
super.key,
required this.apiClient,
});
@override
Widget build(BuildContext context) {
final activeTheme = AppTheme.activePreset;
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Meine Watchlist & Favoriten', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: activeTheme.textPrimary)),
const SizedBox(height: 4),
Text('Synchronisiert über alle Geräte hinweg.', style: TextStyle(color: activeTheme.textMuted, fontSize: 13)),
const SizedBox(height: 16),
Expanded(
child: BlocBuilder<FavoritesCubit, FavoritesState>(
builder: (context, state) {
if (state.isLoading && state.favoriteDetails.isEmpty) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 260,
mainAxisExtent: 140,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
),
itemCount: 6,
itemBuilder: (context, index) => ShimmerLoading(width: 260, height: 140),
);
}
final favorites = state.favoriteDetails;
if (favorites.isEmpty) {
return Center(
child: Text(
'Noch keine Favoriten gespeichert.\nFüge Wertpapiere über die Suchleiste oder Asset-Karten hinzu.',
textAlign: TextAlign.center,
style: TextStyle(color: activeTheme.textMuted, height: 1.4),
),
);
}
return GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 260,
mainAxisExtent: 140,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
),
itemCount: favorites.length,
itemBuilder: (context, index) {
final asset = favorites[index];
return WatchlistCard(
asset: asset,
apiClient: apiClient,
);
},
);
},
),
),
],
),
),
);
}
}