import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../core/network/api_client.dart'; import '../../core/network/signalr_service.dart'; import '../../core/theme/app_theme.dart'; import '../../core/theme/theme_cubit.dart'; import '../../features/admin/views/admin_evaluation_history_screen.dart'; import '../../features/admin/views/admin_users_screen.dart'; import '../../features/auth/models/user_model.dart'; import '../../features/bot/views/bot_control_panel_screen.dart'; import '../../features/calendar/views/corporate_calendar_screen.dart'; import '../../features/dashboard/views/dashboard_screen.dart'; import '../../features/discovery/cubit/discovery_cubit.dart'; import '../../features/favorites/cubit/favorites_cubit.dart'; import '../../features/favorites/views/favorites_screen.dart'; import '../../features/news/views/news_feed_screen.dart'; import '../../features/simulation/views/backtest_visualizer_screen.dart'; import '../../features/trades/views/trades_feed_screen.dart'; import 'global_app_bar.dart'; /// Main Responsive Shell consuming root FavoritesCubit and ThemeCubit state. class ResponsiveScaffold extends StatefulWidget { final UserModel user; final ApiClient apiClient; final SignalRService signalRService; const ResponsiveScaffold({ super.key, required this.user, required this.apiClient, required this.signalRService, }); @override State createState() => _ResponsiveScaffoldState(); } class _ResponsiveScaffoldState extends State { int _selectedIndex = 0; @override void initState() { super.initState(); // Load favorites immediately after auth is confirmed and widget is mounted. // Using addPostFrameCallback ensures the BlocProvider tree is fully built. WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { context.read().loadFavorites(); context.read().loadDiscovery(); } }); } List get _tabTitles => [ 'Dashboard', 'News Feed', 'Favoriten', 'Kalender', 'Live Trades', if (widget.user.isAdmin) 'Bot Panel', if (widget.user.isAdmin) 'Backtest', if (widget.user.isAdmin) 'Admin Panel', if (widget.user.isAdmin) 'Evaluierungs-Historie', ]; @override Widget build(BuildContext context) { final bool isDesktop = MediaQuery.of(context).size.width >= 800; final titles = _tabTitles; final activeTitle = _selectedIndex < titles.length ? titles[_selectedIndex] : 'Dashboard'; final List pages = [ DashboardScreen(apiClient: widget.apiClient, signalRService: widget.signalRService), NewsFeedScreen(apiClient: widget.apiClient), FavoritesScreen(apiClient: widget.apiClient), CorporateCalendarScreen(apiClient: widget.apiClient), TradesFeedScreen(apiClient: widget.apiClient, signalRService: widget.signalRService), if (widget.user.isAdmin) BotControlPanelScreen(apiClient: widget.apiClient, signalRService: widget.signalRService), if (widget.user.isAdmin) BacktestVisualizerScreen(apiClient: widget.apiClient), if (widget.user.isAdmin) AdminUsersScreen(apiClient: widget.apiClient, signalRService: widget.signalRService), if (widget.user.isAdmin) AdminEvaluationHistoryScreen(apiClient: widget.apiClient), ]; return BlocBuilder( builder: (context, themeState) { final activeTheme = themeState.preset; return Scaffold( backgroundColor: activeTheme.darkBackground, appBar: GlobalAppBar( user: widget.user, apiClient: widget.apiClient, signalRService: widget.signalRService, currentTabTitle: activeTitle, ), body: isDesktop ? Row( children: [ _DesktopSidebar( selectedIndex: _selectedIndex, isAdmin: widget.user.isAdmin, onDestinationSelected: (idx) => setState(() => _selectedIndex = idx), ), VerticalDivider(width: 1, color: activeTheme.glassBorder), Expanded( child: AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: pages[_selectedIndex], ), ), ], ) : AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: pages[_selectedIndex], ), bottomNavigationBar: isDesktop ? null : BottomNavigationBar( currentIndex: _selectedIndex, onTap: (idx) => setState(() => _selectedIndex = idx), backgroundColor: activeTheme.cardSurface, selectedItemColor: activeTheme.primaryColor, unselectedItemColor: activeTheme.textMuted, type: BottomNavigationBarType.fixed, items: [ const BottomNavigationBarItem(icon: Icon(Icons.dashboard_rounded), label: 'Dashboard'), const BottomNavigationBarItem(icon: Icon(Icons.newspaper_rounded), label: 'News'), const BottomNavigationBarItem(icon: Icon(Icons.star_rounded), label: 'Favoriten'), const BottomNavigationBarItem(icon: Icon(Icons.calendar_month_rounded), label: 'Kalender'), const BottomNavigationBarItem(icon: Icon(Icons.candlestick_chart_rounded), label: 'Trades'), if (widget.user.isAdmin) const BottomNavigationBarItem(icon: Icon(Icons.smart_toy_outlined), label: 'Bot'), if (widget.user.isAdmin) const BottomNavigationBarItem(icon: Icon(Icons.query_stats_rounded), label: 'Backtest'), if (widget.user.isAdmin) const BottomNavigationBarItem(icon: Icon(Icons.admin_panel_settings_outlined), label: 'Admin'), if (widget.user.isAdmin) const BottomNavigationBarItem(icon: Icon(Icons.history_rounded), label: 'Historie'), ], ), ); }, ); } } class _DesktopSidebar extends StatelessWidget { final int selectedIndex; final bool isAdmin; final ValueChanged onDestinationSelected; const _DesktopSidebar({ required this.selectedIndex, required this.isAdmin, required this.onDestinationSelected, }); @override Widget build(BuildContext context) { final activeTheme = AppTheme.activePreset; return Container( width: 220, color: activeTheme.cardSurface, child: ListView( padding: const EdgeInsets.symmetric(vertical: 12), children: [ _navTile(activeTheme, 0, Icons.dashboard_rounded, 'Dashboard'), _navTile(activeTheme, 1, Icons.newspaper_rounded, 'News Feed'), _navTile(activeTheme, 2, Icons.star_rounded, 'Favoriten'), _navTile(activeTheme, 3, Icons.calendar_month_rounded, 'Kalender'), _navTile(activeTheme, 4, Icons.candlestick_chart_rounded, 'Live Trades'), if (isAdmin) _navTile(activeTheme, 5, Icons.smart_toy_outlined, 'Bot Panel'), if (isAdmin) _navTile(activeTheme, 6, Icons.query_stats_rounded, 'Backtest'), if (isAdmin) _navTile(activeTheme, 7, Icons.admin_panel_settings_outlined, 'Admin Panel'), if (isAdmin) _navTile(activeTheme, 8, Icons.history_rounded, 'Evaluierungs-Historie'), ], ), ); } Widget _navTile(ThemePreset activeTheme, int index, IconData icon, String label) { final isSelected = selectedIndex == index; return Container( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 3), child: ListTile( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(activeTheme.borderRadius * 0.7)), selected: isSelected, selectedTileColor: activeTheme.primaryColor.withValues(alpha: 0.15), leading: Icon(icon, color: isSelected ? activeTheme.primaryColor : activeTheme.textSecondary, size: 20), title: Text( label, style: TextStyle( color: isSelected ? activeTheme.primaryColor : activeTheme.textSecondary, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, fontSize: 13, ), ), onTap: () => onDestinationSelected(index), ), ); } }