import 'dart:convert'; import 'dart:io'; // Tambahkan ini import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; // Tambahkan ini untuk SystemNavigator.pop import 'package:http/http.dart' as http; import 'package:google_fonts/google_fonts.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../layout/main_layout.dart'; import '../pages/petugas_drawer.dart'; import '../pages/login_page.dart'; class DashboardAdminPage extends StatefulWidget { const DashboardAdminPage({super.key}); @override State createState() => _DashboardAdminPageState(); } class _DashboardAdminPageState extends State { bool _isAuthorized = false; bool _isLoading = true; String userName = "Loading..."; int jumlahKader = 0; int jumlahBidan = 0; int jumlahDesa = 0; int jumlahDusun = 0; final String dashboardUrl = "http://ta.myhost.id/E31230549/mposyandu_api/dashboard_admin.php"; @override void initState() { super.initState(); _initPage(); } Future _initPage() async { final prefs = await SharedPreferences.getInstance(); final isLogin = prefs.getBool("isLogin") ?? false; if (!isLogin) { if (!mounted) return; Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => const LoginPage(fromGuard: true)), (route) => false, ); return; } setState(() { _isAuthorized = true; String? savedName = prefs.getString('nama'); userName = (savedName == null || savedName.isEmpty) ? "Admin" : savedName; }); await fetchDashboard(); } Future fetchDashboard() async { if (!_isAuthorized) return; try { final response = await http.get(Uri.parse(dashboardUrl)); if (response.statusCode == 200) { final data = json.decode(response.body); if (data["success"] == true) { if (mounted) { setState(() { jumlahKader = data["jumlah_kader"] ?? 0; jumlahBidan = data["jumlah_bidan"] ?? 0; jumlahDesa = data["jumlah_desa"] ?? 0; jumlahDusun = data["jumlah_dusun"] ?? 0; _isLoading = false; }); } } } } catch (e) { debugPrint("ERROR DASHBOARD: $e"); if (mounted) setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { // Logika Responsif double screenWidth = MediaQuery.of(context).size.width; // Jika lebar layar > 700px (Desktop/Tablet), gunakan 4 kolom. Jika tidak (HP), 2 kolom. int crossAxisCount = screenWidth > 700 ? 4 : 2; // Mengatur rasio tinggi kartu agar tetap proporsional double aspectRatio = screenWidth > 700 ? 1.5 : 1.1; // Membungkus dengan PopScope agar ketika klik back button aplikasi keluar return PopScope( canPop: false, // Menahan aksi "back" standar navigator onPopInvokedWithResult: (didPop, result) { if (didPop) return; // Keluar dari aplikasi secara total if (Platform.isAndroid) { SystemNavigator.pop(); } else if (Platform.isIOS) { exit(0); } }, child: MainLayout( title: " ", drawer: const DrawerPetugas(), body: RefreshIndicator( onRefresh: fetchDashboard, child: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // HEADER AREA RichText( text: TextSpan( children: [ TextSpan( text: 'Selamat Datang Admin\n', style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.black54), ), TextSpan( text: userName, style: GoogleFonts.poppins( fontSize: 22, fontWeight: FontWeight.w700, color: const Color(0xFF1385E2)), ), ], ), ), const SizedBox(height: 25), // GRID AREA (Dinamis berdasarkan perangkat) GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: crossAxisCount, crossAxisSpacing: 15, mainAxisSpacing: 15, childAspectRatio: aspectRatio, children: [ _card( "Kader", jumlahKader, Icons.groups, Colors.blue), _card("Bidan", jumlahBidan, Icons.medical_services, Colors.green), _card("Desa", jumlahDesa, Icons.location_city, Colors.orange), _card("Dusun", jumlahDusun, Icons.map, Colors.purple), ], ), ], ), ), ), ), ); } Widget _card(String title, int val, IconData icon, Color color) { return Container( decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: color.withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 5), ) ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: Colors.white, size: 28), const SizedBox(height: 8), Text( val.toString(), style: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), Text( title, style: const TextStyle( color: Colors.white70, fontSize: 12, letterSpacing: 0.5, ), ), ], ), ); } }