import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../utils/api_config.dart'; import 'package:fl_chart/fl_chart.dart'; import 'search_route_screen.dart'; import 'history_screen.dart'; import 'history_detail_screen.dart'; import 'profile_screen.dart'; // Tambahkan import Profil // Import session manager untuk nama dinamis import '../utils/session_manager.dart'; import '../widgets/responsive_layout.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { int _selectedIndex = 0; final List _pages; _HomeScreenState() : _pages = [] { _pages.addAll([ HomeDashboardContent(onPlanRoute: () => _onItemTapped(1)), const SearchRouteScreen(), const HistoryScreen(), const ProfileScreen(), ]); } void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { return ResponsiveLayout( child: PopScope( canPop: false, onPopInvoked: (didPop) { if (didPop) return; if (_selectedIndex != 0) { setState(() { _selectedIndex = 0; }); } }, child: Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: _pages[_selectedIndex], bottomNavigationBar: BottomNavigationBar( currentIndex: _selectedIndex, onTap: _onItemTapped, type: BottomNavigationBarType.fixed, selectedItemColor: Colors.blue, unselectedItemColor: Colors.grey, selectedLabelStyle: const TextStyle(fontWeight: FontWeight.bold, fontSize: 12), unselectedLabelStyle: const TextStyle(fontSize: 12), items: const [ BottomNavigationBarItem(icon: Icon(Icons.home_filled), label: 'Home'), BottomNavigationBarItem(icon: Icon(Icons.location_searching), label: 'Cari Rute'), BottomNavigationBarItem(icon: Icon(Icons.history), label: 'Riwayat'), BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profil'), ], ), ), ), ); } } class HomeDashboardContent extends StatefulWidget { final VoidCallback onPlanRoute; const HomeDashboardContent({super.key, required this.onPlanRoute}); @override State createState() => _HomeDashboardContentState(); } class _HomeDashboardContentState extends State { bool _isWeekly = true; // Toggle Mingguan/Bulanan List _history = []; List _recentRoutes = []; double _totalDistance = 0; int _totalSeconds = 0; bool _isLoading = true; int _selectedMonth = DateTime.now().month; int _selectedYear = DateTime.now().year; int _selectedWeekIndex = 0; // 0: Semua Minggu (Bulanan), 1-4: Minggu spesifik int? _selectedIndex; // Index titik yang dipilih di grafik List _chartDataPoints = []; List _chartLabels = []; double _maxDistance = 10.0; @override void initState() { super.initState(); _loadDashboardData(); } String _getMonthName(int month) { const names = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]; return names[month - 1]; } String _getShortMonthName(int month) { const names = ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des"]; return names[month - 1]; } List> _getWeekRanges(int month, int year) { List> ranges = []; DateTime date = DateTime(year, month, 1); int daysToSunday = (7 - date.weekday) % 7; DateTime currentSunday = date.add(Duration(days: daysToSunday)); while (currentSunday.month == month) { DateTime saturday = currentSunday.add(const Duration(days: 6)); ranges.add({ 'start': currentSunday, 'end': saturday, }); currentSunday = currentSunday.add(const Duration(days: 7)); } return ranges; } List _generateWeeks(int month, int year) { List weeks = ["Semua Minggu"]; List> ranges = _getWeekRanges(month, year); for (var range in ranges) { DateTime start = range['start']!; DateTime end = range['end']!; if (start.month == end.month) { weeks.add("${start.day} - ${end.day} ${_getMonthName(start.month)}"); } else { weeks.add("${start.day} ${_getMonthName(start.month)} - ${end.day} ${_getMonthName(end.month)}"); } } return weeks; } Future _loadDashboardData() async { final url = Uri.parse("${ApiConfig.baseUrl}/get_history.php?id_users=${SessionManager.userId}"); try { final response = await http.get(url); if (response.statusCode == 200) { List decodedHistory = jsonDecode(response.body); setState(() { _history = decodedHistory; _recentRoutes = decodedHistory.take(3).toList(); _calculateStats(); _isLoading = false; }); } } catch (e) { debugPrint("Gagal memuat data riwayat dari server: $e"); setState(() { _isLoading = false; }); } } void _calculateStats() { double dist = 0; int secs = 0; DateTime startDate; DateTime endDate; List> ranges = _getWeekRanges(_selectedMonth, _selectedYear); if (_selectedWeekIndex == 0) { _isWeekly = false; if (ranges.isNotEmpty) { startDate = ranges.first['start']!; endDate = ranges.last['end']!; _chartDataPoints = List.filled(ranges.length, 0.0); _chartLabels = []; for (var range in ranges) { DateTime start = range['start']!; DateTime end = range['end']!; if (start.month == end.month) { _chartLabels.add("${start.day}-${end.day} ${_getShortMonthName(start.month)}"); } else { _chartLabels.add("${start.day} ${_getShortMonthName(start.month)}-${end.day} ${_getShortMonthName(end.month)}"); } } } else { startDate = DateTime(_selectedYear, _selectedMonth, 1); endDate = DateTime(_selectedYear, _selectedMonth + 1, 0); _chartDataPoints = []; _chartLabels = []; } } else { _isWeekly = true; int index = _selectedWeekIndex - 1; if (index >= 0 && index < ranges.length) { startDate = ranges[index]['start']!; endDate = ranges[index]['end']!; int daysCount = endDate.difference(startDate).inDays + 1; _chartDataPoints = List.filled(daysCount, 0.0); const dayNames = ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"]; _chartLabels = List.generate(daysCount, (i) { DateTime d = startDate.add(Duration(days: i)); return "${dayNames[d.weekday % 7]}, ${d.day}"; }); } else { startDate = DateTime(_selectedYear, _selectedMonth, 1); endDate = DateTime(_selectedYear, _selectedMonth + 1, 0); _chartDataPoints = []; _chartLabels = []; } } for (var trip in _history) { DateTime tripDate = DateTime.parse(trip['tanggal']); if (tripDate.isAfter(startDate.subtract(const Duration(seconds: 1))) && tripDate.isBefore(endDate.add(const Duration(days: 1)))) { double tripDist = double.tryParse(trip['jarak_tempuh']?.toString() ?? "0") ?? 0; int tripSecs = int.tryParse(trip['waktu_tempuh']?.toString() ?? "0") ?? 0; int dataIndex = -1; if (_isWeekly) { dataIndex = tripDate.difference(startDate).inDays; } else { for (int i = 0; i < ranges.length; i++) { if (tripDate.isAfter(ranges[i]['start']!.subtract(const Duration(seconds: 1))) && tripDate.isBefore(ranges[i]['end']!.add(const Duration(days: 1)))) { dataIndex = i; break; } } } if (dataIndex >= 0 && dataIndex < _chartDataPoints.length) { _chartDataPoints[dataIndex] += tripDist; if (_selectedIndex == null || _selectedIndex == dataIndex) { dist += tripDist; secs += tripSecs; } } } } double maxVal = _chartDataPoints.isNotEmpty ? _chartDataPoints.reduce((a, b) => a > b ? a : b) : 0; _maxDistance = maxVal > 0 ? maxVal : 10.0; setState(() { _totalDistance = dist; _totalSeconds = secs; }); } String _formatDuration(int seconds) { if (seconds <= 0) return "0 menit"; int h = seconds ~/ 3600; int m = (seconds % 3600) ~/ 60; if (h > 0) return "$h jam $m menit"; return "$m menit"; } String getStatSubtitle(bool isDistance) { if (_selectedIndex != null) { if (_isWeekly) { return isDistance ? "Total jarak yang Anda tempuh pada hari ini" : "Total durasi yang Anda tempuh pada hari ini"; } else { return isDistance ? "Total jarak yang Anda tempuh pada minggu ini" : "Total durasi yang Anda tempuh pada minggu ini"; } } else { if (_isWeekly) { return isDistance ? "Total jarak yang Anda tempuh pada minggu ini" : "Total durasi yang Anda tempuh pada minggu ini"; } else { return isDistance ? "Total jarak yang Anda tempuh pada bulan ini" : "Total durasi yang Anda tempuh pada bulan ini"; } } } @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; return Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: isDark ? [const Color(0xFF121212), const Color(0xFF1E1E1E), const Color(0xFF121212)] : [const Color(0xFFF8FAFC), const Color(0xFFF1F5F9), const Color(0xFFE2E8F0)], ), ), child: SafeArea( child: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Selamat ${DateTime.now().hour < 12 ? "Pagi" : DateTime.now().hour < 15 ? "Siang" : DateTime.now().hour < 18 ? "Sore" : "Malam"},', style: TextStyle(fontSize: 14, color: isDark ? Colors.blueGrey.shade200 : Colors.blueGrey, fontWeight: FontWeight.w500)), const SizedBox(height: 4), Text( SessionManager.userName ?? "User", style: TextStyle( fontSize: 28, fontWeight: FontWeight.w900, color: isDark ? Colors.white : const Color(0xFF1E293B), letterSpacing: -0.5 ), ), ], ), ], ), const SizedBox(height: 24), Text('Tren Aktivitas Anda', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: isDark ? Colors.white : const Color(0xFF1E293B), letterSpacing: -0.5)), const SizedBox(height: 16), Row( children: [ Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( color: isDark ? const Color(0xFF252836) : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade200), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: _selectedMonth, isExpanded: true, items: List.generate(12, (i) => DropdownMenuItem( value: i + 1, child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text(_getMonthName(i + 1)), ), )), onChanged: (val) { setState(() { _selectedMonth = val!; _selectedWeekIndex = 0; _selectedIndex = null; _calculateStats(); }); }, ), ), ), ), const SizedBox(width: 16), Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( color: isDark ? const Color(0xFF252836) : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade200), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: _selectedWeekIndex, isExpanded: true, items: List.generate(_generateWeeks(_selectedMonth, _selectedYear).length, (i) => DropdownMenuItem( value: i, child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text(_generateWeeks(_selectedMonth, _selectedYear)[i]), ), )), onChanged: (val) { setState(() { _selectedWeekIndex = val!; _selectedIndex = null; _calculateStats(); }); }, ), ), ), ), ], ), const SizedBox(height: 20), _buildActivityChart(), const SizedBox(height: 24), // --- KARTU STATISTIK --- Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildStatCard( 'Jarak', '${_totalDistance.toStringAsFixed(1)} km', Icons.directions_bike, Colors.blue, getStatSubtitle(true) ), const SizedBox(width: 16), _buildStatCard( 'Waktu', _formatDuration(_totalSeconds), Icons.timer, Colors.orange, getStatSubtitle(false) ), ], ), const SizedBox(height: 32), // --- KARTU VISUAL GRADIENT --- _buildPlanRouteCard(context), const SizedBox(height: 32), Text('Rute Terakhir', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: isDark ? Colors.white : const Color(0xFF1E293B), letterSpacing: -0.5)), const SizedBox(height: 16), _recentRoutes.isEmpty ? const Text("Belum ada rute yang diselesaikan", style: TextStyle(color: Colors.grey)) : Column( children: _recentRoutes.map((route) => _buildRecentRouteItem(route)).toList(), ), ], ), ), ), ), ); } Widget _buildFilterChip(String label, bool isActive, VoidCallback onTap) { final isDark = Theme.of(context).brightness == Brightness.dark; return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: isActive ? Colors.blueAccent : (isDark ? const Color(0xFF1E1E1E) : Colors.white), borderRadius: BorderRadius.circular(12), border: Border.all(color: isActive ? Colors.blueAccent : (isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade200)), boxShadow: isActive ? [BoxShadow(color: Colors.blue.withOpacity(isDark ? 0.1 : 0.2), blurRadius: 8)] : null, ), child: Center( child: Text( label, style: TextStyle( color: isActive ? Colors.white : Colors.grey.shade600, fontWeight: FontWeight.bold, fontSize: 12, ), ), ), ), ); } Widget _buildActivityChart() { final isDark = Theme.of(context).brightness == Brightness.dark; return Container( height: 240, width: double.infinity, padding: const EdgeInsets.fromLTRB(15, 25, 20, 10), decoration: BoxDecoration( color: isDark ? const Color(0xFF1E1E1E) : Colors.white, borderRadius: BorderRadius.circular(28), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(isDark ? 0.3 : 0.04), blurRadius: 24, offset: const Offset(0, 12), ), ], border: isDark ? Border.all(color: Colors.white.withOpacity(0.05), width: 1) : null, ), child: _chartDataPoints.isEmpty ? const Center(child: Text("Tidak ada data", style: TextStyle(color: Colors.grey))) : LineChart( LineChartData( gridData: FlGridData( show: true, drawVerticalLine: true, horizontalInterval: 0.2, verticalInterval: 1, getDrawingHorizontalLine: (value) => FlLine(color: isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade100, strokeWidth: 1), getDrawingVerticalLine: (value) => FlLine(color: isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade100, strokeWidth: 1), ), titlesData: FlTitlesData( show: true, rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 30, interval: 1, getTitlesWidget: (value, meta) { int index = value.toInt(); if (index >= 0 && index < _chartLabels.length) { return SideTitleWidget( axisSide: meta.axisSide, child: Text( _chartLabels[index], style: TextStyle( color: _selectedIndex == index ? Colors.orangeAccent : (isDark ? Colors.white54 : Colors.grey), fontSize: 10, fontWeight: _selectedIndex == index ? FontWeight.bold : FontWeight.normal, ), ), ); } return const SizedBox(); }, ), ), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 45, interval: _maxDistance > 0 ? (_maxDistance / 5).ceilToDouble().clamp(1.0, 100.0) : 2.0, getTitlesWidget: (value, meta) { return SideTitleWidget( axisSide: meta.axisSide, child: Text( "${value.toStringAsFixed(0)} km", style: TextStyle(color: isDark ? Colors.white54 : Colors.grey, fontSize: 10), ), ); }, ), ), ), borderData: FlBorderData( show: false, ), minX: 0, maxX: (_chartDataPoints.length - 1).toDouble(), minY: 0, maxY: (_maxDistance * 1.25).ceilToDouble(), lineBarsData: [ LineChartBarData( spots: List.generate(_chartDataPoints.length, (i) => FlSpot(i.toDouble(), _chartDataPoints[i])), isCurved: true, color: Colors.blueAccent, barWidth: 3, isStrokeCapRound: true, dotData: FlDotData( show: true, getDotPainter: (spot, percent, barData, index) { bool isSelected = _selectedIndex == index; return FlDotCirclePainter( radius: isSelected ? 6 : 4, color: isSelected ? Colors.orangeAccent : Colors.blue, strokeWidth: 2, strokeColor: Colors.white, ); }, ), belowBarData: BarAreaData( show: true, color: Colors.blueAccent.withOpacity(0.05), ), ), ], lineTouchData: LineTouchData( touchCallback: (FlTouchEvent event, LineTouchResponse? touchResponse) { if (!event.isInterestedForInteractions || touchResponse == null || touchResponse.lineBarSpots == null) { return; } if (event is FlTapDownEvent || event is FlTapUpEvent) { final spotIndex = touchResponse.lineBarSpots!.first.spotIndex; setState(() { if (_selectedIndex == spotIndex) { _selectedIndex = null; } else { _selectedIndex = spotIndex; } _calculateStats(); }); } }, handleBuiltInTouches: true, ), ), ), ); } Widget _buildStatCard(String title, String value, IconData icon, Color color, String subtitle) { final isDark = Theme.of(context).brightness == Brightness.dark; return Expanded( child: Container( clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: isDark ? const Color(0xFF252836) : Colors.white, borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: isDark ? Colors.black.withOpacity(0.4) : color.withOpacity(0.1), blurRadius: 15, offset: const Offset(0, 8), ), ], border: Border.all( color: isDark ? Colors.white.withOpacity(0.05) : Colors.grey.shade200, width: 1, ), ), child: Stack( children: [ // Thick left accent border Positioned( left: 0, top: 0, bottom: 0, child: Container(width: 6, color: color), ), Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: color.withOpacity(0.15), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: color, size: 22), ), const SizedBox(height: 16), Text( value, style: TextStyle( fontSize: 24, fontWeight: FontWeight.w900, color: isDark ? Colors.white : const Color(0xFF1E293B), letterSpacing: -0.5 ) ), const SizedBox(height: 4), Text( title, style: TextStyle( color: isDark ? Colors.white.withOpacity(0.9) : Colors.blueGrey.shade700, fontSize: 14, fontWeight: FontWeight.w700 ) ), const SizedBox(height: 6), Text( subtitle, style: TextStyle( color: isDark ? Colors.white54 : Colors.grey.shade500, fontSize: 11, fontStyle: FontStyle.italic, height: 1.2 ) ), ], ), ), ], ), ), ); } Widget _buildPlanRouteCard(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(24), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF3B82F6), Color(0xFF2563EB)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(28), boxShadow: [ BoxShadow( color: Colors.blue.withOpacity(0.3), blurRadius: 25, offset: const Offset(0, 12), ) ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Siap untuk gowes hari ini?', style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: -0.5)), const SizedBox(height: 8), const Text('Temukan rute terbaik yang aman dan nyaman untukmu.', style: TextStyle(color: Colors.white70, fontSize: 14, fontWeight: FontWeight.w500)), const SizedBox(height: 24), ElevatedButton( onPressed: widget.onPlanRoute, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.blue.shade700, elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Text('Mulai Jelajah', style: TextStyle(fontWeight: FontWeight.w800)), SizedBox(width: 8), Icon(Icons.arrow_forward_rounded, size: 16), ], ), ), ], ), ); } Widget _buildNotificationBadge(BuildContext context) { return Stack( children: [ IconButton( onPressed: () => ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Belum ada notifikasi baru"))), icon: const Icon(Icons.notifications_active, color: Colors.blueAccent, size: 30), ), Positioned( right: 8, top: 8, child: Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration(color: Colors.red, shape: BoxShape.circle), constraints: const BoxConstraints(minWidth: 8, minHeight: 8), ), ) ], ); } Widget _buildRecentRouteItem(dynamic route) { final isDark = Theme.of(context).brightness == Brightness.dark; String name = route['nama_rute'] ?? '-'; String distance = '${route['jarak_tempuh'] ?? route['jarak'] ?? 0} km'; String statusText = route['status']?.toString().toUpperCase() ?? 'GAGAL'; if (statusText == "0") statusText = "GAGAL"; return GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => HistoryDetailScreen(historyItem: route), ), ); }, child: Container( margin: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: isDark ? const Color(0xFF1E1E1E) : Colors.white, borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(isDark ? 0.2 : 0.03), blurRadius: 20, offset: const Offset(0, 8), ), ], border: isDark ? Border.all(color: Colors.white.withOpacity(0.05), width: 1) : null, ), child: Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue.shade400, Colors.blue.shade700], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow(color: Colors.blue.withOpacity(isDark ? 0.1 : 0.3), blurRadius: 8, offset: const Offset(0, 4)) ], ), child: const Icon(Icons.directions_bike_rounded, color: Colors.white, size: 24), ), const SizedBox(width: 18), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: TextStyle( fontWeight: FontWeight.w800, fontSize: 15, color: isDark ? Colors.white : const Color(0xFF1E293B) ), overflow: TextOverflow.ellipsis ), const SizedBox(height: 6), Row( children: [ Icon(Icons.straighten, size: 14, color: isDark ? Colors.blueGrey.shade400 : Colors.blueGrey.shade300), const SizedBox(width: 4), Text( distance, style: TextStyle( color: isDark ? Colors.blueGrey.shade300 : Colors.blueGrey.shade400, fontSize: 13, fontWeight: FontWeight.w500 ) ), const SizedBox(width: 12), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: statusText == "BERHASIL" ? Colors.green.withOpacity(0.1) : Colors.red.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Text( statusText, style: TextStyle( color: statusText == "BERHASIL" ? Colors.greenAccent : Colors.redAccent, fontSize: 10, fontWeight: FontWeight.w900 ) ), ), ], ), ], ), ), Icon(Icons.arrow_forward_ios_rounded, size: 16, color: isDark ? Colors.white24 : Colors.blueGrey.shade200), ], ), ), ); } }