import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:english_learning/core/widgets/custom_button.dart'; import 'package:english_learning/features/auth/provider/user_provider.dart'; import 'package:english_learning/features/history/provider/history_provider.dart'; import 'package:english_learning/features/history/screens/history_screen.dart'; import 'package:english_learning/features/home/data/card_data.dart'; import 'package:english_learning/features/home/provider/completed_topics_provider.dart'; import 'package:english_learning/features/home/widgets/progress_card.dart'; import 'package:english_learning/features/home/widgets/welcome_card.dart'; import 'package:english_learning/features/learning/screens/learning_screen.dart'; import 'package:english_learning/features/settings/modules/edit_profile/screens/edit_profile_screen.dart'; import 'package:english_learning/features/settings/screens/settings_screen.dart'; import 'package:english_learning/core/widgets/slider_widget.dart'; import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_nav_bar/google_nav_bar.dart'; import 'package:provider/provider.dart'; import 'package:shimmer/shimmer.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); static void navigateToTab(BuildContext context, int index) { final state = context.findAncestorStateOfType<_HomeScreenState>(); if (state != null) { state.navigateToTab(index); } } static void navigateReplacing(BuildContext context) { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => const HomeScreen()), ); } } class _HomeScreenState extends State { final PageController _pageController = PageController(); int _selectedIndex = 0; final List _screens = [ const HomeContent(), const LearningScreen(), const HistoryScreen(), const SettingsScreen(), ]; void navigateToTab(int index) { setState(() { _selectedIndex = index; _pageController.jumpToPage(index); }); } @override Widget build(BuildContext context) { return DefaultTabController( length: 4, child: Scaffold( body: Container( color: AppColors.bgSoftColor, child: PageView( physics: const NeverScrollableScrollPhysics(), controller: _pageController, children: _screens, onPageChanged: (index) { setState(() { _selectedIndex = index; }); }, ), ), bottomNavigationBar: Container( decoration: BoxDecoration( gradient: AppColors.gradientTheme, borderRadius: const BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), child: Padding( padding: const EdgeInsets.only( top: 20, bottom: 24, left: 16, right: 16, ), child: GNav( activeColor: AppColors.blueColor, tabBackgroundColor: AppColors.whiteColor, tabBorderRadius: 100, color: AppColors.whiteColor, iconSize: 20, gap: 8, selectedIndex: _selectedIndex, onTabChange: (index) async { if (index == 2 && _selectedIndex != 2) { // Only if switching TO history tab final historyProvider = Provider.of(context, listen: false); final userProvider = Provider.of(context, listen: false); if (!historyProvider.isInitialized) { await historyProvider .loadInitialData(userProvider.jwtToken!); } } navigateToTab(index); }, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), tabs: const [ GButton( icon: BootstrapIcons.house, text: 'Home', ), GButton( icon: BootstrapIcons.book, text: 'Learning', ), GButton( icon: BootstrapIcons.clock_history, text: 'History', ), GButton( icon: BootstrapIcons.gear, text: 'Settings', ), ], ), ), ), ), ); } } class HomeContent extends StatefulWidget { const HomeContent({super.key}); @override State createState() => _HomeContentState(); } class _HomeContentState extends State { final CardData cardData = CardData(); int _currentPage = 0; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _initializeData(); }); } Future _initializeData() async { final userProvider = Provider.of(context, listen: false); final completedTopicsProvider = Provider.of(context, listen: false); try { // Reset data sebelum fetch completedTopicsProvider.resetData(); // Fetch completed topics await completedTopicsProvider .fetchCompletedTopics(userProvider.jwtToken!); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to load data: ${e.toString()}'), action: SnackBarAction( label: 'Retry', onPressed: _initializeData, ), ), ); } } } Widget _buildErrorWidget(String error) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.error_outline, size: 48, color: Colors.red[300], ), const SizedBox(height: 16), Text( 'Oops! Something went wrong', style: AppTextStyles.blackTextStyle.copyWith( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( error, textAlign: TextAlign.center, style: AppTextStyles.disableTextStyle.copyWith(fontSize: 14), ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: _initializeData, icon: const Icon(Icons.refresh), label: const Text('Retry'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryColor, foregroundColor: Colors.white, ), ), ], ), ); } Widget _buildNoDataWidget() { return Padding( padding: const EdgeInsets.all(12.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Still new?', style: AppTextStyles.blackTextStyle.copyWith( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( 'Begin your journey!', style: AppTextStyles.disableTextStyle.copyWith( fontSize: 14, ), ), const SizedBox(height: 24), CustomButton( text: 'Explore', width: double.infinity, height: 44, color: AppColors.yellowButtonColor, onPressed: () { HomeScreen.navigateToTab(context, 1); }, ), ], ), ); } Widget _buildProgressCard(CompletedTopicsProvider provider) { if (provider.error != null) { return _buildErrorWidget(provider.error!); } if (provider.completedTopics.isEmpty) { return _buildNoDataWidget(); } return _buildCompletedTopicsContent(provider); } Widget _buildCompletedTopicsContent(CompletedTopicsProvider provider) { return AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: ListView.builder( key: ValueKey(provider.completedTopics.length), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 16.0), itemCount: 1, itemBuilder: (context, index) { return ProgressCard( completedTopic: provider.completedTopics, ); }, ), ); } Widget _buildLoadingWidget() { return Shimmer.fromColors( baseColor: Colors.grey[300]!, highlightColor: Colors.grey[100]!, child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: double.infinity, height: 20, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 16), Row( children: [ Expanded( flex: 2, child: Container( height: 80, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), ), ), const SizedBox(width: 16), Expanded( flex: 3, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: double.infinity, height: 16, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 8), Container( width: double.infinity, height: 16, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), ], ), ), ], ), ], ), ), ); } @override Widget build(BuildContext context) { return RefreshIndicator( onRefresh: _initializeData, child: Consumer2( builder: (context, authProvider, completedTopicsProvider, child) { final userName = authProvider.getUserName() ?? 'Guest'; return SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: double.infinity, decoration: BoxDecoration( gradient: AppColors.gradientTheme, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24), ), ), child: Padding( padding: const EdgeInsets.only( top: 60.0, left: 18.34, right: 16.0, bottom: 34.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ SvgPicture.asset( 'lib/features/home/assets/images/Logo.svg', width: 31, ), const SizedBox(width: 4.34), Text( 'SEALS', style: AppTextStyles.logoTextStyle .copyWith( fontSize: 28, fontWeight: FontWeight.w700, ), ), ], ), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const EditProfileScreen(), ), ); }, child: const Icon( BootstrapIcons.person_circle, size: 28, color: AppColors.whiteColor, ), ), ], ), const SizedBox(height: 17), RichText( text: TextSpan( text: 'Hi, ', style: AppTextStyles.whiteTextStyle.copyWith( fontWeight: FontWeight.w700, fontSize: 18, ), children: [ TextSpan( text: userName, style: AppTextStyles.yellowTextStyle .copyWith( fontWeight: FontWeight.w700, fontSize: 18, ), ), TextSpan( text: '!', style: AppTextStyles.whiteTextStyle.copyWith( fontWeight: FontWeight.w700, fontSize: 18, ), ), ], ), ), const SizedBox(height: 8), Text( 'Let\'s evolve together', style: AppTextStyles.whiteTextStyle.copyWith( fontSize: 12, fontWeight: FontWeight.w400, ), ), ], ), ), ), ], ), ], ), const SizedBox(height: 16), CarouselSlider.builder( itemCount: cardData.cardData.length, itemBuilder: (context, index, realIndex) { return WelcomeCard(cardModel: cardData.cardData[index]); }, options: CarouselOptions( height: 168, viewportFraction: 0.9, enlargeCenterPage: true, autoPlay: true, autoPlayInterval: const Duration(seconds: 3), autoPlayAnimationDuration: const Duration(milliseconds: 800), autoPlayCurve: Curves.fastOutSlowIn, onPageChanged: (index, reason) { setState( () { _currentPage = index; }, ); }, ), ), const SizedBox(height: 16), SliderWidget( currentPage: _currentPage, itemCount: cardData.cardData.length, ), const SizedBox(height: 16), Padding( padding: const EdgeInsets.only( top: 8.0, left: 24.0, right: 24.0, bottom: 47.0, ), child: Container( width: double.infinity, decoration: BoxDecoration( color: AppColors.whiteColor, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.2), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Row( children: [ const Icon( BootstrapIcons.info_circle, color: AppColors.tetriaryColor, size: 16, ), const SizedBox(width: 8), Text( 'Your Last Journey.', style: AppTextStyles.tetriaryTextStyle.copyWith( fontSize: 12, fontWeight: FontWeight.w800, ), ), ], ), ), AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: completedTopicsProvider.isLoading ? _buildLoadingWidget() : _buildProgressCard(completedTopicsProvider), ), ], ), ), ), ], ), ); }), ); } }