import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:sijentik/component/app_theme.dart'; import 'history_page.dart'; import 'add_report.dart'; import 'reports_page.dart'; import 'profile_page.dart'; import 'package:shared_preferences/shared_preferences.dart'; class DashboardPage extends StatefulWidget { final Map user; const DashboardPage({super.key, required this.user}); @override State createState() => _DashboardPageState(); } class _DashboardPageState extends State { String address = ''; @override void initState() { super.initState(); loadUserData(); } Future loadUserData() async { final prefs = await SharedPreferences.getInstance(); setState(() { address = prefs.getString('address') ?? ''; }); } // Data statistik dummy final Map stats = const { 'totalReports': 24, 'approved': 18, 'pending': 4, 'rejected': 2, 'percentage': 75, }; // Data laporan terbaru dummy final List> recentReports = const [ { 'id': 'LP001', 'address': 'Jl. Merdeka No. 12', 'date': '12 Mar 2024', 'status': 'Disetujui', 'statusColor': Colors.green, }, { 'id': 'LP002', 'address': 'Jl. Sudirman No. 45', 'date': '11 Mar 2024', 'status': 'Menunggu', 'statusColor': Colors.orange, }, { 'id': 'LP003', 'address': 'Jl. Gatot Subroto No. 8', 'date': '10 Mar 2024', 'status': 'Disetujui', 'statusColor': Colors.green, }, ]; @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // ===== HEADER SELAMAT DATANG ===== Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: const Color(0xFF206E97), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Selamat Datang,', style: TextStyle(fontSize: 16, color: Colors.white70), ), const SizedBox(height: 5), Text( widget.user['name'] ?? 'Kader', style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 10), Text( 'Wilayah: ${widget.user['address']}', style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(0.9), ), ), const SizedBox(height: 5), Text( 'Total Laporan: ${stats['totalReports']}', style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(0.9), ), ), ], ), ), const SizedBox(width: 20), Container( width: 80, height: 80, decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), shape: BoxShape.circle, ), child: const Icon( Icons.medical_services_outlined, size: 40, color: Colors.white, ), ), ], ), ), const SizedBox(height: 25), // ===== STATISTIK CARD ===== const Text( 'Statistik Laporan', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 15), GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, crossAxisSpacing: 15, mainAxisSpacing: 15, childAspectRatio: 1.2, children: [ _buildStatCard( title: 'Total Laporan', value: '${stats['totalReports']}', icon: Icons.assignment_outlined, color: const Color(0xFF206E97), ), _buildStatCard( title: 'Disetujui', value: '${stats['approved']}', icon: Icons.check_circle_outline, color: Colors.green, ), _buildStatCard( title: 'Menunggu', value: '${stats['pending']}', icon: Icons.access_time_outlined, color: Colors.orange, ), _buildStatCard( title: 'Ditolak', value: '${stats['rejected']}', icon: Icons.cancel_outlined, color: Colors.red, ), ], ), const SizedBox(height: 25), // ===== PERSENTASE DISETUJUI ===== Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Row( children: [ Stack( alignment: Alignment.center, children: [ SizedBox( width: 80, height: 80, child: CircularProgressIndicator( value: stats['percentage'] / 100, strokeWidth: 8, backgroundColor: Colors.grey[200], valueColor: const AlwaysStoppedAnimation( Color(0xFF206E97), ), ), ), Text( '${stats['percentage']}%', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(width: 20), const Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Persentase Disetujui', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), ), SizedBox(height: 5), Text( '75% laporan Anda telah disetujui petugas. Pertahankan!', style: TextStyle(fontSize: 14, color: Colors.grey), ), ], ), ), ], ), ), const SizedBox(height: 25), // ===== LAPORAN TERBARU ===== Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Laporan Terbaru', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87, ), ), TextButton( onPressed: () { // Navigasi ke halaman riwayat // Navigator.push(context, MaterialPageRoute(builder: (context) => HistoryPage())); }, child: const Text( 'Lihat Semua', style: TextStyle(color: Color(0xFF206E97)), ), ), ], ), const SizedBox(height: 10), Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( children: recentReports.map((report) { return Column( children: [ ListTile( leading: Container( width: 40, height: 40, decoration: BoxDecoration( color: const Color(0xFF206E97).withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: const Icon( Icons.home_outlined, color: Color(0xFF206E97), size: 20, ), ), title: Text( report['address'], style: const TextStyle(fontWeight: FontWeight.w500), ), subtitle: Text( 'ID: ${report['id']} • ${report['date']}', style: const TextStyle(fontSize: 12), ), trailing: Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: report['statusColor'].withOpacity(0.1), borderRadius: BorderRadius.circular(20), ), child: Text( report['status'], style: TextStyle( color: report['statusColor'], fontSize: 12, fontWeight: FontWeight.w500, ), ), ), onTap: () { // Navigasi ke detail laporan }, ), if (report != recentReports.last) const Divider(height: 1, indent: 16, endIndent: 16), ], ); }).toList(), ), ), const SizedBox(height: 25), const SizedBox(height: 40), ], ), ); } Widget _buildStatCard({ required String title, required String value, required IconData icon, required Color color, }) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), padding: const EdgeInsets.all(16), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Icon(icon, color: color, size: 20), ), const Spacer(), Text( value, style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ], ), const SizedBox(height: 12), Text( title, style: const TextStyle( fontSize: 13, color: Colors.grey, fontWeight: FontWeight.w500, ), ), ], ), ); } Widget _buildQuickActionCard({ required IconData icon, required String title, required String subtitle, required Color color, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Icon(icon, color: color, size: 24), ), const SizedBox(height: 12), Text( title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black87, ), ), const SizedBox(height: 4), Text( subtitle, style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ], ), ), ); } }