Files
Finlytic/FinlyticApp/lib/features/dashboard/widgets/favorites_carousel.dart
T

135 lines
5.1 KiB
Dart

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/asset_logo_widget.dart';
import '../../../core/widgets/glass_container.dart';
import '../../../shared/widgets/favorite_star_button.dart';
import '../../asset_detail/views/asset_detail_screen.dart';
import '../../favorites/cubit/favorites_cubit.dart';
/// Dynamic User Favorites Carousel widget bound to FavoritesCubit with real-time SignalR prices.
class FavoritesCarousel extends StatelessWidget {
final ApiClient apiClient;
const FavoritesCarousel({
super.key,
required this.apiClient,
});
@override
Widget build(BuildContext context) {
return BlocBuilder<FavoritesCubit, FavoritesState>(
builder: (context, state) {
final activeTheme = AppTheme.activePreset;
final favoritesList = state.favoriteDetails;
if (favoritesList.isEmpty) {
return GlassContainer(
padding: const EdgeInsets.all(16),
child: Center(
child: Text(
'Keine Favoriten vorhanden. Nutze die Suche (Lupe), um Wertpapiere hinzuzufügen.',
style: TextStyle(color: activeTheme.textMuted, fontSize: 13),
),
),
);
}
return SizedBox(
height: 110,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: favoritesList.length,
itemBuilder: (context, index) {
final fav = favoritesList[index];
final displayName = fav.name.isNotEmpty
? fav.name
: (fav.symbol.isNotEmpty ? fav.symbol : fav.isin);
final isinOrSymbol = fav.isin.isNotEmpty
? fav.isin
: (fav.symbol.isNotEmpty ? fav.symbol : fav.name);
final isPositive = fav.change24h >= 0;
return Container(
width: 195,
margin: const EdgeInsets.only(right: 12),
child: GlassContainer(
padding: const EdgeInsets.all(12),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => AssetDetailScreen(
symbol: isinOrSymbol,
apiClient: apiClient,
),
),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
AssetLogoWidget(
symbolOrName: isinOrSymbol,
imageUrl: fav.image.isNotEmpty ? fav.image : null,
size: 24,
),
const SizedBox(width: 8),
Expanded(
child: Text(
displayName,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
color: activeTheme.textPrimary),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
FavoriteStarButton(
identifier: isinOrSymbol,
symbol: fav.symbol,
name: fav.name,
size: 18,
padding: EdgeInsets.zero,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${fav.currentPrice > 0 ? fav.currentPrice.toStringAsFixed(2) : '--.--'}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12.5,
color: activeTheme.textPrimary,
),
),
Text(
'${isPositive ? '+' : ''}${fav.change24h.toStringAsFixed(2)}%',
style: TextStyle(
color: isPositive ? AppTheme.primaryEmerald : AppTheme.accentRed,
fontWeight: FontWeight.bold,
fontSize: 11.5,
),
),
],
),
],
),
),
);
},
),
);
},
);
}
}