TIFNGK_E41221954/lib/screens/kader/dashboardkader.dart

479 lines
15 KiB
Dart

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<String, dynamic> user;
const DashboardPage({super.key, required this.user});
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
String address = '';
@override
void initState() {
super.initState();
loadUserData();
}
Future<void> loadUserData() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
address = prefs.getString('address') ?? '';
});
}
// Data statistik dummy
final Map<String, dynamic> stats = const {
'totalReports': 24,
'approved': 18,
'pending': 4,
'rejected': 2,
'percentage': 75,
};
// Data laporan terbaru dummy
final List<Map<String, dynamic>> 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>(
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]),
),
],
),
),
);
}
}