import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:tugas_akhir_supabase/screens/calendar/calendar_screen.dart'; import 'package:tugas_akhir_supabase/screens/calendar/schedule_list_screen.dart'; import 'package:tugas_akhir_supabase/screens/calendar/schedule_detail_screen.dart'; import 'package:tugas_akhir_supabase/screens/community/community_screen.dart'; import 'package:tugas_akhir_supabase/screens/panen/analisis_panen_screen.dart'; import 'package:tugas_akhir_supabase/screens/profile_screen.dart'; import 'package:tugas_akhir_supabase/models/crop_schedule.dart'; import 'package:tugas_akhir_supabase/screens/home/home_content.dart'; import 'package:tugas_akhir_supabase/screens/panen/analisis_input_screen.dart'; import 'package:tugas_akhir_supabase/utils/date_formatter.dart'; import 'package:tugas_akhir_supabase/screens/image_processing/plant_scanner_screen.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State { User? _user; int _selectedIndex = 0; String? _profileImageUrl; Map? _profile; String? _scheduleId; String? _cropName; bool _isLoadingSchedule = true; DateTime? _lastBackPressed; // Variabel untuk melacak apakah perlu refresh bool _needsHomeRefresh = false; List get _screens { final userId = _user?.id ?? ''; return [ HomeContent( userId: userId, // Tambahkan parameter refresh key yang akan berubah saat perlu refresh key: ValueKey( 'home_content_${_needsHomeRefresh ? 'refresh' : 'normal'}', ), ), KalenderTanamScreen(), PlantScannerScreen(), _buildAnalisisScreen(userId), CommunityScreen(), ]; } @override void initState() { super.initState(); _user = Supabase.instance.client.auth.currentUser; _loadUserProfile(); _fetchScheduleIfNeeded(); } Future _loadUserProfile() async { if (_user == null) { debugPrint('FATAL: User is null, cannot load profile'); return; } debugPrint('INFO: Current user ID: ${_user!.id}'); debugPrint('INFO: Current user email: ${_user!.email}'); try { debugPrint('INFO: Mencoba mencari profile untuk user ID: ${_user!.id}'); // Coba dengan query langsung ke tabel final response = await Supabase.instance.client .from('profiles') .select('*') .eq('user_id', _user!.id) .limit(1); debugPrint('QUERY RESULT: Hasil query length: ${response.length}'); debugPrint('QUERY RESULT: Response: $response'); if (response.isNotEmpty) { final userData = response[0]; debugPrint('SUCCESS: Profile data ditemukan'); debugPrint('DATA: Full profile: $userData'); debugPrint('DATA: farm_name: ${userData['farm_name']}'); debugPrint('DATA: user_id: ${userData['user_id']}'); if (mounted) { setState(() { _profileImageUrl = userData['avatar_url']; _profile = userData; }); } } else { debugPrint( 'FATAL: Tidak ada data profile ditemukan untuk user_id: ${_user!.id}', ); // Fallback: Create a temporary profile for UI if (mounted) { setState(() { _profile = { 'farm_name': 'pepepe', // Gunakan nama yang kita tahu ada 'user_id': _user!.id, }; }); } } } catch (e, stackTrace) { debugPrint('ERROR: Gagal mengambil profile: $e'); debugPrint('STACKTRACE: $stackTrace'); } } Future _onWillPop() async { final now = DateTime.now(); if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) { _lastBackPressed = now; ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Tekan sekali lagi untuk keluar'), duration: Duration(seconds: 2), ), ); return false; } return true; // keluar aplikasi } Future _fetchScheduleIfNeeded() async { if (_user == null) { setState(() => _isLoadingSchedule = false); return; } try { final schedule = await fetchActiveSchedule(_user!.id); if (mounted) { setState(() { _scheduleId = schedule?['scheduleId']; _cropName = schedule?['cropName']; _isLoadingSchedule = false; }); } } catch (e) { debugPrint('Error saat ambil schedule: $e'); if (mounted) { setState(() => _isLoadingSchedule = false); } } } void _onItemTapped(int index) { // Jika sebelumnya berada di tab lain dan kembali ke home tab if (_selectedIndex != 0 && index == 0 && _needsHomeRefresh) { // Reset flag dan rebuild HomeContent dengan key baru setState(() { _needsHomeRefresh = false; }); } setState(() { _selectedIndex = index; }); } // Tandai bahwa home screen perlu di-refresh void _markHomeNeedsRefresh() { setState(() { _needsHomeRefresh = true; }); } void _navigateToProfile() { Navigator.push( context, MaterialPageRoute(builder: (context) => ProfileScreen()), ).then((_) { // Reload profile when returning from profile screen _loadUserProfile(); }); } Widget _buildAnalisisScreen(String userId) { if (_isLoadingSchedule) { return Center(child: CircularProgressIndicator()); } return AnalisisInputScreen( userId: userId, scheduleData: _scheduleId != null ? {'id': _scheduleId, 'crop_name': _cropName} : null, ); } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) async { if (didPop) return; final shouldExit = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Konfirmasi'), content: const Text('Apakah Anda ingin keluar dari aplikasi?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Tidak'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('Keluar'), ), ], ), ); if (shouldExit == true) { SystemNavigator.pop(); } }, child: Scaffold( backgroundColor: const Color(0xFFFAFAFA), body: SafeArea( child: Column( children: [ _buildHeader(), Expanded( child: IndexedStack(index: _selectedIndex, children: _screens), ), ], ), ), bottomNavigationBar: _buildBottomNavBar(), ), ); } Widget _buildHeader() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), offset: const Offset(0, 1), blurRadius: 2, ), ], ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'TaniSM4RT', style: GoogleFonts.poppins( fontSize: 22, fontWeight: FontWeight.bold, color: const Color(0xFF056839), ), ), const SizedBox(height: 2), Text( _getUserDisplayName(), style: GoogleFonts.poppins( fontSize: 14, color: Colors.grey[600], ), ), ], ), GestureDetector( onTap: _navigateToProfile, child: Container( height: 40, width: 40, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey[200], image: _profileImageUrl != null ? DecorationImage( image: NetworkImage(_profileImageUrl!), fit: BoxFit.cover, ) : null, border: Border.all(color: Colors.white, width: 1.5), ), child: _profileImageUrl == null ? const Icon( Icons.person, color: Colors.grey, size: 20, ) : null, ), ), ], ), ], ), ); } Widget _buildBottomNavBar() { return Container( height: 60, decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 4, offset: const Offset(0, -1), ), ], ), child: BottomNavigationBar( currentIndex: _selectedIndex, onTap: _onItemTapped, backgroundColor: Colors.white, type: BottomNavigationBarType.fixed, selectedItemColor: const Color(0xFF056839), unselectedItemColor: Colors.grey, selectedFontSize: 11, unselectedFontSize: 11, iconSize: 22, selectedLabelStyle: GoogleFonts.poppins(fontWeight: FontWeight.w500), unselectedLabelStyle: GoogleFonts.poppins(fontWeight: FontWeight.w500), elevation: 0, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home_rounded), label: 'Beranda', ), BottomNavigationBarItem( icon: Icon(Icons.calendar_today_rounded), label: 'Kalender', ), BottomNavigationBarItem( icon: Icon(Icons.document_scanner_rounded), label: 'Scan', ), BottomNavigationBarItem( icon: Icon(Icons.insights_rounded), label: 'Analisis', ), BottomNavigationBarItem( icon: Icon(Icons.forum_rounded), label: 'Komunitas', ), ], ), ); } String _getUserDisplayName() { debugPrint('DIAGNOSIS: Mencoba mendapatkan nama display'); debugPrint('DIAGNOSIS: Profile ada? ${_profile != null}'); if (_profile != null) { debugPrint('DIAGNOSIS: Isi profile: $_profile'); debugPrint('DIAGNOSIS: Keys dalam profile: ${_profile!.keys.toList()}'); } // Prioritaskan username dari database if (_profile != null && _profile!['username'] != null && _profile!['username'].toString().isNotEmpty) { final username = _profile!['username'].toString(); debugPrint('DIAGNOSIS: Menggunakan username dari database: $username'); return 'Hi, $username'; } // Fallback ke farm_name if (_profile != null && _profile!['farm_name'] != null && _profile!['farm_name'].toString().isNotEmpty) { final farmName = _profile!['farm_name'].toString(); debugPrint('DIAGNOSIS: Menggunakan farm_name dari database: $farmName'); return 'Hi, $farmName'; } // Fallback ke email if (_user != null && _user!.email != null) { final email = _user!.email!; final username = email.split('@').first; debugPrint('DIAGNOSIS: Menggunakan nama dari email: $username'); return 'Hi, $username'; } return 'Hi, Petani'; } Future?> fetchActiveSchedule(String userId) async { try { final response = await Supabase.instance.client .from('crop_schedules') .select('id, crop_name') .eq('user_id', userId) .order('created_at', ascending: false) .limit(1) .single(); if (response['id'] != null && response['crop_name'] != null) { return { 'scheduleId': response['id'], 'cropName': response['crop_name'], }; } } catch (e) { debugPrint('Gagal fetch schedule: $e'); } return null; } }