From c90c5356e58f87f17e7353cd7cdf2c6cef84f04c Mon Sep 17 00:00:00 2001 From: BakoL2323 <142969559+ardiyanto1234@users.noreply.github.com> Date: Thu, 16 Apr 2026 00:53:28 +0700 Subject: [PATCH] update --- assets/images/logo_petugas.png | Bin 0 -> 64905 bytes lib/api/api.dart | 2 + lib/controller/register_controller.dart | 32 +- lib/screens/auth/AuthService.dart | 4 +- lib/screens/auth/KaderService.dart | 3 +- lib/screens/auth/buatsandibaru.dart | 23 +- lib/screens/auth/dashboardService.dart | 6 +- lib/screens/auth/login.dart | 83 +++- lib/screens/auth/lupasandiemail.dart | 9 +- lib/screens/auth/lupasandiotp.dart | 7 +- lib/screens/kader/add_report.dart | 20 +- lib/screens/kader/dashboardkader.dart | 470 ++++++++-------------- lib/screens/kader/homekader.dart | 46 +-- lib/screens/kader/profile_page.dart | 20 +- lib/screens/kader/reports_page.dart | 22 +- lib/screens/petugas/daftarkader.dart | 299 +++++++++----- lib/screens/petugas/dashboardpetugas.dart | 4 +- lib/screens/petugas/laporanpetugas.dart | 13 +- lib/screens/petugas/verifikasikader.dart | 122 ++---- pubspec.yaml | 1 + 20 files changed, 584 insertions(+), 602 deletions(-) create mode 100644 assets/images/logo_petugas.png create mode 100644 lib/api/api.dart diff --git a/assets/images/logo_petugas.png b/assets/images/logo_petugas.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd45b46c93e78c996561cc699ed299768033941 GIT binary patch literal 64905 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 AfdBvi literal 0 HcmV?d00001 diff --git a/lib/api/api.dart b/lib/api/api.dart new file mode 100644 index 0000000..9d535f2 --- /dev/null +++ b/lib/api/api.dart @@ -0,0 +1,2 @@ +const String baseUrl = 'http://192.168.1.6:8000/api'; +const String baseImageurl = 'http://192.168.1.6:8000/'; \ No newline at end of file diff --git a/lib/controller/register_controller.dart b/lib/controller/register_controller.dart index ea9a544..9e5540b 100644 --- a/lib/controller/register_controller.dart +++ b/lib/controller/register_controller.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:sijentik/api/api.dart'; class RegisterResult { final bool success; @@ -10,7 +11,6 @@ class RegisterResult { } class RegisterKaderController extends ChangeNotifier { - final formKey = GlobalKey(); final namaController = TextEditingController(); @@ -24,9 +24,6 @@ class RegisterKaderController extends ChangeNotifier { bool obscureKonfirmasiPassword = true; bool isLoading = false; - /// GANTI DENGAN URL API LARAVEL ANDA - final String baseUrl = "http://192.168.1.6:8000/api/register"; - void togglePassword() { obscurePassword = !obscurePassword; notifyListeners(); @@ -85,24 +82,17 @@ class RegisterKaderController extends ChangeNotifier { } Future register() async { - if (!formKey.currentState!.validate()) { - return RegisterResult( - success: false, - message: "Form belum lengkap", - ); + return RegisterResult(success: false, message: "Form belum lengkap"); } isLoading = true; notifyListeners(); try { - final response = await http.post( - Uri.parse(baseUrl), - headers: { - "Content-Type": "application/json", - }, + Uri.parse('$baseUrl/register'), // 🔥 pakai baseUrl global + headers: {"Content-Type": "application/json"}, body: jsonEncode({ "name": namaController.text, "email": emailController.text, @@ -112,34 +102,24 @@ class RegisterKaderController extends ChangeNotifier { "password_confirmation": konfirmasiPasswordController.text, }), ); - final data = jsonDecode(response.body); if (response.statusCode == 201) { - return RegisterResult( success: true, message: data["message"] ?? "Register berhasil", ); - } else { - return RegisterResult( success: false, - message: data["message"] ?? - data["error"] ?? - "Register gagal", + message: data["message"] ?? data["error"] ?? "Register gagal", ); - } - } catch (e) { - return RegisterResult( success: false, message: "Tidak dapat terhubung ke server", ); - } finally { isLoading = false; notifyListeners(); @@ -159,4 +139,4 @@ class RegisterKaderController extends ChangeNotifier { konfirmasiPasswordController.dispose(); super.dispose(); } -} \ No newline at end of file +} diff --git a/lib/screens/auth/AuthService.dart b/lib/screens/auth/AuthService.dart index 705983f..e1cf0d6 100644 --- a/lib/screens/auth/AuthService.dart +++ b/lib/screens/auth/AuthService.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:sijentik/api/api.dart'; class RegisterResult { final bool success; @@ -14,9 +15,6 @@ class RegisterResult { } class AuthService { - // Android Emulator => 10.0.2.2 - // HP fisik => ganti dengan IP laptop/PC, misalnya 192.168.1.10 - static const String baseUrl = 'http://192.168.1.6:8000'; Future registerKader({ required String name, diff --git a/lib/screens/auth/KaderService.dart b/lib/screens/auth/KaderService.dart index dd8762e..e021d16 100644 --- a/lib/screens/auth/KaderService.dart +++ b/lib/screens/auth/KaderService.dart @@ -1,10 +1,9 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +import 'package:sijentik/api/api.dart'; class KaderService { - final String baseUrl = "http://192.168.1.6:8000/api"; - Future approveKader(int id) async { try { diff --git a/lib/screens/auth/buatsandibaru.dart b/lib/screens/auth/buatsandibaru.dart index eba42a7..bcdd564 100644 --- a/lib/screens/auth/buatsandibaru.dart +++ b/lib/screens/auth/buatsandibaru.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:sijentik/api/api.dart'; class BuatKataSandiBaruPage extends StatefulWidget { final String email; @@ -22,11 +23,6 @@ class _BuatKataSandiBaruPageState extends State { bool obscurePassword = true; bool obscureConfirmPassword = true; - // Android Emulator: 10.0.2.2 - // HP Fisik: ganti dengan IP laptop, misalnya 192.168.1.8 - static const String resetPasswordUrl = - 'http://192.168.1.6:8000/api/reset-password'; - @override void dispose() { passwordController.dispose(); @@ -70,10 +66,7 @@ class _BuatKataSandiBaruPageState extends State { ), ), const SizedBox(height: 30), - Image.asset( - 'assets/images/sandidua.png', - width: 150, - ), + Image.asset('assets/images/sandidua.png', width: 150), Padding( padding: const EdgeInsets.all(24.0), child: Column( @@ -198,8 +191,7 @@ class _BuatKataSandiBaruPageState extends State { ), onPressed: () { setState(() { - obscureConfirmPassword = - !obscureConfirmPassword; + obscureConfirmPassword = !obscureConfirmPassword; }); }, ), @@ -304,17 +296,14 @@ class _BuatKataSandiBaruPageState extends State { try { final response = await http.post( - Uri.parse(resetPasswordUrl), - headers: { - 'Accept': 'application/json', - }, + Uri.parse('$baseUrl/reset-password'), // 🔥 pakai baseUrl global + headers: {'Accept': 'application/json'}, body: { 'email': widget.email, 'password': passwordController.text.trim(), 'password_confirmation': confirmPasswordController.text.trim(), }, ); - final dynamic data = jsonDecode(response.body); if (!mounted) return; @@ -365,4 +354,4 @@ class _BuatKataSandiBaruPageState extends State { ); } } -} \ No newline at end of file +} diff --git a/lib/screens/auth/dashboardService.dart b/lib/screens/auth/dashboardService.dart index 62a0870..3d0b877 100644 --- a/lib/screens/auth/dashboardService.dart +++ b/lib/screens/auth/dashboardService.dart @@ -1,12 +1,10 @@ import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/foundation.dart'; +import 'package:sijentik/api/api.dart'; class DashboardService { - static const String baseUrl = "http://192.168.1.6:8000/api"; - // kalau pakai HP asli ganti ke IP laptop, misalnya: - // static const String baseUrl = "http://192.168.1.8:8000/api"; - + static Future?> getDashboard() async { try { final url = Uri.parse("$baseUrl/dashboard-petugas"); diff --git a/lib/screens/auth/login.dart b/lib/screens/auth/login.dart index 1453fcc..0613020 100644 --- a/lib/screens/auth/login.dart +++ b/lib/screens/auth/login.dart @@ -6,6 +6,7 @@ import 'package:sijentik/component/app_theme.dart'; import 'package:sijentik/screens/auth/registerkader.dart'; import 'package:sijentik/screens/auth/lupasandiemail.dart'; import 'package:sijentik/screens/kader/homekader.dart'; +import 'package:sijentik/api/api.dart'; import 'package:sijentik/screens/petugas/dashboardpetugas.dart'; class LoginPage extends StatefulWidget { @@ -25,8 +26,6 @@ class _LoginPageState extends State { bool obscurePassword = true; bool isLoading = false; - static const String baseUrl = 'http://192.168.1.6:8000/api/login'; - @override void dispose() { emailController.dispose(); @@ -39,10 +38,10 @@ class _LoginPageState extends State { // ============================= // SIMPAN DATA USER // ============================= - Future saveUserData(Map user) async { + Future saveUserData(Map user) async { final prefs = await SharedPreferences.getInstance(); - await prefs.setInt('id', user['id']); + await prefs.setInt('id', int.tryParse(user['id'].toString()) ?? 0); await prefs.setString('name', user['name'] ?? ''); await prefs.setString('email', user['email'] ?? ''); await prefs.setString('address', user['address'] ?? ''); @@ -51,6 +50,9 @@ class _LoginPageState extends State { await prefs.setString('status', user['status'] ?? ''); } + // ============================= + // LOGIN + // ============================= Future _login() async { if (emailController.text.isEmpty || passwordController.text.isEmpty) { _showErrorDialog('Email dan kata sandi harus diisi'); @@ -68,7 +70,7 @@ class _LoginPageState extends State { try { final response = await http.post( - Uri.parse(baseUrl), + Uri.parse('$baseUrl/login'), headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', @@ -79,6 +81,9 @@ class _LoginPageState extends State { }), ); + print("STATUS LOGIN: ${response.statusCode}"); + print("BODY LOGIN: ${response.body}"); + final data = jsonDecode(response.body); if (!mounted) return; @@ -88,9 +93,18 @@ class _LoginPageState extends State { }); if (response.statusCode == 200) { - final user = data['user']; + final user = Map.from(data['user'] ?? {}); - // simpan data user dari backend + // 🔥 VALIDASI WAJIB + if (user['id'] == null) { + _showErrorDialog('ID user tidak ditemukan dari server'); + return; + } + + print("LOGIN SUCCESS"); + print("USER FINAL: $user"); + + // SIMPAN await saveUserData(user); final String role = (user['role'] ?? '').toString().toLowerCase(); @@ -98,7 +112,13 @@ class _LoginPageState extends State { if (role == 'petugas') { _navigateToDashboardPetugas(); } else if (role == 'kader') { - _navigateToHomeKader(user); + _navigateToHomeKader({ + 'id': user['id'], + 'name': user['name'], + 'email': user['email'], + 'address': user['address'], + 'role': user['role'], + }); } else { _showErrorDialog('Role pengguna tidak dikenali'); } @@ -116,6 +136,9 @@ class _LoginPageState extends State { } } + // ============================= + // ERROR DIALOG + // ============================= void _showErrorDialog(String message) { showDialog( context: context, @@ -197,7 +220,6 @@ class _LoginPageState extends State { ), const SizedBox(height: 30), - // EMAIL Align( alignment: Alignment.centerLeft, child: Text( @@ -225,7 +247,6 @@ class _LoginPageState extends State { const SizedBox(height: 20), - // PASSWORD Align( alignment: Alignment.centerLeft, child: Text( @@ -264,7 +285,23 @@ class _LoginPageState extends State { onSubmitted: (_) => _login(), ), - const SizedBox(height: 25), + const SizedBox(height: 10), + + Row( + children: [ + TextButton( + onPressed: _navigateLupaKataSandi, + child: const Text( + 'Lupa Kata Sandi?', + style: TextStyle( + color: Color(0xFF1E88E5), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 10), SizedBox( width: double.infinity, @@ -283,24 +320,24 @@ class _LoginPageState extends State { style: TextStyle( fontSize: 17, fontWeight: FontWeight.bold, + color: Colors.white, ), ), ), ), - - const SizedBox(height: 25), + const SizedBox(height: 15), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( + const Text( 'Belum punya akun? ', - style: TextStyle(color: Colors.grey[700]), + style: TextStyle(color: Colors.black87), ), - TextButton( - onPressed: _navigateToRegister, + GestureDetector( + onTap: _navigateToRegister, child: const Text( - 'Daftar disini', + 'Daftar', style: TextStyle( color: Color(0xFF1E88E5), fontWeight: FontWeight.bold, @@ -313,7 +350,6 @@ class _LoginPageState extends State { ), ), ), - const SizedBox(height: 40), ], ), ), @@ -324,7 +360,6 @@ class _LoginPageState extends State { } void _navigateToHomeKader(Map user) { - FocusScope.of(context).unfocus(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => HomeKaderPage(user: user)), @@ -333,7 +368,6 @@ class _LoginPageState extends State { } void _navigateToDashboardPetugas() { - FocusScope.of(context).unfocus(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const DashboardPetugas()), @@ -347,4 +381,11 @@ class _LoginPageState extends State { MaterialPageRoute(builder: (context) => const RegisterKaderPage()), ); } + + void _navigateLupaKataSandi() { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const LupaKataSandiEmailPage()), + ); + } } diff --git a/lib/screens/auth/lupasandiemail.dart b/lib/screens/auth/lupasandiemail.dart index 01ec6b3..d294a02 100644 --- a/lib/screens/auth/lupasandiemail.dart +++ b/lib/screens/auth/lupasandiemail.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'lupasandiotp.dart'; +import 'package:sijentik/api/api.dart'; class LupaKataSandiEmailPage extends StatefulWidget { const LupaKataSandiEmailPage({super.key}); @@ -14,11 +15,6 @@ class _LupaKataSandiEmailPageState extends State { final TextEditingController emailController = TextEditingController(); final FocusNode emailFocusNode = FocusNode(); - // Ganti sesuai device yang dipakai - // Android Emulator: 10.0.2.2 - // HP Fisik: pakai IP laptop, misalnya 192.168.1.8 - static const String requestOtpUrl = 'http://192.168.1.6:8000/api/RequestOtp'; - @override void dispose() { emailController.dispose(); @@ -226,11 +222,10 @@ class _LupaKataSandiEmailPageState extends State { try { final response = await http.post( - Uri.parse(requestOtpUrl), + Uri.parse('$baseUrl/request-otp'), // 🔥 pakai baseUrl global headers: {'Accept': 'application/json'}, body: {'email': emailController.text.trim(), 'type': 'email'}, ); - final dynamic data = jsonDecode(response.body); if (!mounted) return; diff --git a/lib/screens/auth/lupasandiotp.dart b/lib/screens/auth/lupasandiotp.dart index c021ef5..3be5424 100644 --- a/lib/screens/auth/lupasandiotp.dart +++ b/lib/screens/auth/lupasandiotp.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'buatsandibaru.dart'; +import 'package:sijentik/api/api.dart'; class LupaKataSandiOtpPage extends StatefulWidget { final String email; @@ -24,10 +25,8 @@ class _LupaKataSandiOtpPageState extends State { (index) => FocusNode(), ); - // Android Emulator: 10.0.2.2 - // HP Fisik: ganti dengan IP laptop, misalnya 192.168.1.8 - static const String verifyOtpUrl = 'http://192.168.1.6:8000/api/verify-otp'; - static const String requestOtpUrl = 'http://192.168.1.6:8000/api/RequestOtp'; + String get verifyOtpUrl => '$baseUrl/verify-otp'; + String get requestOtpUrl => '$baseUrl/RequestOtp'; @override void initState() { diff --git a/lib/screens/kader/add_report.dart b/lib/screens/kader/add_report.dart index 3d20bc8..fb6e44d 100644 --- a/lib/screens/kader/add_report.dart +++ b/lib/screens/kader/add_report.dart @@ -7,9 +7,11 @@ import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:sijentik/models/report_model.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:sijentik/api/api.dart'; class AddReportPage extends StatefulWidget { - const AddReportPage({super.key}); + const AddReportPage({super.key, required userId}); @override State createState() => _AddReportPageState(); @@ -29,8 +31,6 @@ class _AddReportPageState extends State { final ImagePicker picker = ImagePicker(); - static const String baseUrl = 'http://192.168.1.6:8000/api'; - Future simpanLaporan() async { if (judulController.text.trim().isEmpty) { _showMessage('Judul laporan wajib diisi'); @@ -52,12 +52,25 @@ class _AddReportPageState extends State { }); try { + // 🔥 AMBIL TOKEN + final prefs = await SharedPreferences.getInstance(); + final token = prefs.getString('token'); + final userId = prefs.getInt('id'); // 🔥 + final request = http.MultipartRequest( 'POST', Uri.parse('$baseUrl/laporan'), ); request.headers['Accept'] = 'application/json'; + + if (token != null) { + request.headers['Authorization'] = 'Bearer $token'; + } + + // 🔥 TAMBAH INI + request.fields['user_id'] = userId.toString(); + request.fields['judul'] = judulController.text.trim(); request.fields['ada_jentik'] = adaJentik! ? '1' : '0'; request.fields['tanggal'] = DateFormat( @@ -76,7 +89,6 @@ class _AddReportPageState extends State { final streamedResponse = await request.send(); final response = await http.Response.fromStream(streamedResponse); - // PERBAIKAN: data sebagai variable non-final Map? data; if (response.body.isNotEmpty) { data = jsonDecode(response.body); diff --git a/lib/screens/kader/dashboardkader.dart b/lib/screens/kader/dashboardkader.dart index 88e5fe4..87dc33e 100644 --- a/lib/screens/kader/dashboardkader.dart +++ b/lib/screens/kader/dashboardkader.dart @@ -1,5 +1,8 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:sijentik/api/api.dart'; import 'package:sijentik/component/app_theme.dart'; import 'history_page.dart'; import 'add_report.dart'; @@ -17,13 +20,19 @@ class DashboardPage extends StatefulWidget { } class _DashboardPageState extends State { - String address = ''; + Map? dashboardData; + + // 🔥 TAMBAHKAN INI + List recentReports = []; + @override void initState() { super.initState(); loadUserData(); + fetchDashboard(); + fetchRecentReports(); } Future loadUserData() async { @@ -34,58 +43,77 @@ class _DashboardPageState extends State { }); } - // Data statistik dummy - final Map stats = const { - 'totalReports': 24, - 'approved': 18, - 'pending': 4, - 'rejected': 2, - 'percentage': 75, - }; + Future fetchDashboard() async { + final prefs = await SharedPreferences.getInstance(); + final userId = prefs.getInt('id'); - // 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, - }, - ]; + print("ID DARI STORAGE: $userId"); + + if (userId == null) { + print("ID NULL DARI STORAGE ❌"); + return; + } + + final response = await http.get( + Uri.parse('http://192.168.1.6:8000/api/dashboard/$userId'), + ); + + print("STATUS: ${response.statusCode}"); + print("BODY: ${response.body}"); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + + setState(() { + dashboardData = data; + }); + } + } + + Future fetchRecentReports() async { + final prefs = await SharedPreferences.getInstance(); + final userId = prefs.getInt('id'); + + if (userId == null) return; + + final response = await http.get(Uri.parse('$baseUrl/laporan/user/$userId')); + + print("RECENT STATUS: ${response.statusCode}"); + print("RECENT BODY: ${response.body}"); + + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + + setState(() { + recentReports = data; + }); + } + } @override Widget build(BuildContext context) { + final stats = dashboardData?['stats']; + return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // ===== HEADER SELAMAT DATANG ===== + // ===== HEADER (GRADIENT) ===== Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: const Color(0xFF206E97), - borderRadius: BorderRadius.circular(16), + gradient: const LinearGradient( + colors: [Color(0xFF206E97), Color(0xFF4BA3C3)], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.1), + color: Colors.black.withOpacity(0.2), blurRadius: 10, - offset: const Offset(0, 4), + offset: const Offset(0, 5), ), ], ), @@ -96,8 +124,8 @@ class _DashboardPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( - 'Selamat Datang,', - style: TextStyle(fontSize: 16, color: Colors.white70), + 'Selamat Datang 👋', + style: TextStyle(fontSize: 14, color: Colors.white70), ), const SizedBox(height: 5), Text( @@ -108,38 +136,22 @@ class _DashboardPageState extends State { color: Colors.white, ), ), - const SizedBox(height: 10), + const SizedBox(height: 12), Text( - 'Wilayah: ${widget.user['address']}', - style: TextStyle( - fontSize: 14, - color: Colors.white.withOpacity(0.9), - ), + 'Wilayah: ${dashboardData?['user']['wilayah'] ?? '-'}', + style: const TextStyle(color: Colors.white), ), - const SizedBox(height: 5), Text( - 'Total Laporan: ${stats['totalReports']}', - style: TextStyle( - fontSize: 14, - color: Colors.white.withOpacity(0.9), - ), + 'Total Laporan: ${stats?['total_laporan'] ?? 0}', + style: const TextStyle(color: Colors.white), ), ], ), ), - 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 CircleAvatar( + radius: 30, + backgroundColor: Colors.white24, + child: Icon(Icons.person, color: Colors.white, size: 30), ), ], ), @@ -147,14 +159,10 @@ class _DashboardPageState extends State { const SizedBox(height: 25), - // ===== STATISTIK CARD ===== + // ===== STATISTIK ===== const Text( - 'Statistik Laporan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Colors.black87, - ), + "Statistik Laporan", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 15), @@ -162,32 +170,32 @@ class _DashboardPageState extends State { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, - crossAxisSpacing: 15, - mainAxisSpacing: 15, - childAspectRatio: 1.2, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + childAspectRatio: 1.3, children: [ _buildStatCard( - title: 'Total Laporan', - value: '${stats['totalReports']}', - icon: Icons.assignment_outlined, - color: const Color(0xFF206E97), + title: 'Total', + value: '${stats?['total_laporan'] ?? 0}', + icon: Icons.assignment, + color: Colors.blue, ), _buildStatCard( title: 'Disetujui', - value: '${stats['approved']}', - icon: Icons.check_circle_outline, + value: '${stats?['disetujui'] ?? 0}', + icon: Icons.check_circle, color: Colors.green, ), _buildStatCard( title: 'Menunggu', - value: '${stats['pending']}', - icon: Icons.access_time_outlined, + value: '${stats?['menunggu'] ?? 0}', + icon: Icons.schedule, color: Colors.orange, ), _buildStatCard( title: 'Ditolak', - value: '${stats['rejected']}', - icon: Icons.cancel_outlined, + value: '${stats?['ditolak'] ?? 0}', + icon: Icons.cancel, color: Colors.red, ), ], @@ -195,15 +203,15 @@ class _DashboardPageState extends State { const SizedBox(height: 25), - // ===== PERSENTASE DISETUJUI ===== + // ===== PROGRESS ===== Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(16), + borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: Colors.black.withOpacity(0.08), blurRadius: 10, offset: const Offset(0, 4), ), @@ -218,153 +226,104 @@ class _DashboardPageState extends State { width: 80, height: 80, child: CircularProgressIndicator( - value: stats['percentage'] / 100, + value: (stats?['persentase_disetujui'] ?? 0) / 100, strokeWidth: 8, backgroundColor: Colors.grey[200], - valueColor: const AlwaysStoppedAnimation( + valueColor: const AlwaysStoppedAnimation( Color(0xFF206E97), ), ), ), Text( - '${stats['percentage']}%', - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + '${stats?['persentase_disetujui'] ?? 0}%', + style: const TextStyle(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), - ), - ], + child: Text( + "Persentase laporan yang telah disetujui", + style: TextStyle(fontSize: 14), ), ), ], ), ), - 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 - }, + recentReports.isEmpty + ? const Center( + child: Padding( + padding: EdgeInsets.all(20), + child: Text( + "Belum ada laporan", + style: TextStyle(color: Colors.grey), ), - if (report != recentReports.last) - const Divider(height: 1, indent: 16, endIndent: 16), - ], - ); - }).toList(), - ), - ), + ), + ) + : Column( + children: recentReports.map((report) { + return Container( + margin: const EdgeInsets.only(bottom: 12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 6, + ), + ], + ), + child: ListTile( + leading: const Icon(Icons.home, color: Colors.blue), - const SizedBox(height: 25), + // 🔥 FIX FIELD DARI API + title: Text(report['judul'] ?? '-'), + subtitle: Text(report['alamat'] ?? '-'), - const SizedBox(height: 40), + trailing: _buildStatusBadge(report['status']), + ), + ); + }).toList(), + ), ], ), ); } + Widget _buildStatusBadge(String? status) { + Color color; + + switch (status) { + case 'diterima': + color = Colors.green; + break; + case 'proses': + color = Colors.orange; + break; + case 'ditolak': + color = Colors.red; + break; + default: + color = Colors.grey; + } + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(20), + ), + child: Text( + status ?? '-', + style: TextStyle(color: color, fontWeight: FontWeight.bold), + ), + ); + } + Widget _buildStatCard({ required String title, required String value, @@ -372,107 +331,26 @@ class _DashboardPageState extends State { required Color color, }) { return Container( + padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(16), boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 8, - offset: const Offset(0, 2), - ), + BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 8), ], ), - 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), + Icon(icon, color: color, size: 26), + const Spacer(), Text( - title, - style: const TextStyle( - fontSize: 13, - color: Colors.grey, - fontWeight: FontWeight.w500, - ), + value, + style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold), ), + Text(title, style: const TextStyle(color: Colors.grey)), ], ), ); } - - 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]), - ), - ], - ), - ), - ); - } } diff --git a/lib/screens/kader/homekader.dart b/lib/screens/kader/homekader.dart index da19ae6..c20a41c 100644 --- a/lib/screens/kader/homekader.dart +++ b/lib/screens/kader/homekader.dart @@ -19,9 +19,9 @@ class HomeKaderPage extends StatefulWidget { class _HomeKaderPageState extends State { int _selectedIndex = 0; - + // Data dummy kader - + // Pages untuk bottom navigation late final List _pages = [ const DashboardPage(user: {}), @@ -34,7 +34,7 @@ class _HomeKaderPageState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F9FF), - + // APPBAR appBar: AppBar( backgroundColor: AppColors.button, @@ -61,10 +61,7 @@ class _HomeKaderPageState extends State { ), Text( 'Kader: ${widget.user['name']}', - style: const TextStyle( - fontSize: 12, - color: Colors.white70, - ), + style: const TextStyle(fontSize: 12, color: Colors.white70), ), ], ), @@ -95,26 +92,27 @@ class _HomeKaderPageState extends State { const SizedBox(width: 8), ], ), - + // BODY body: _pages[_selectedIndex], - + // FLOATING ACTION BUTTON (hanya di halaman Laporan) - floatingActionButton: _selectedIndex == 1 + floatingActionButton: _selectedIndex == 1 ? FloatingActionButton( backgroundColor: const Color(0xFF206E97), onPressed: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => const AddReportPage(), + builder: (context) => + AddReportPage(userId: widget.user['id']), ), ); }, child: const Icon(Icons.add, color: Colors.white), ) : null, - + // BOTTOM NAVIGATION BAR bottomNavigationBar: BottomNavigationBar( currentIndex: _selectedIndex, @@ -154,7 +152,7 @@ class _HomeKaderPageState extends State { ), ); } - + void _showNotifications() { showDialog( context: context, @@ -191,7 +189,7 @@ class _HomeKaderPageState extends State { }, ); } - + Widget _buildNotificationItem({ required String title, required String message, @@ -217,10 +215,7 @@ class _HomeKaderPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(message), - Text( - time, - style: const TextStyle(fontSize: 12, color: Colors.grey), - ), + Text(time, style: const TextStyle(fontSize: 12, color: Colors.grey)), ], ), trailing: !isRead @@ -235,7 +230,7 @@ class _HomeKaderPageState extends State { : null, ); } - + void _confirmLogout() { showDialog( context: context, @@ -252,19 +247,16 @@ class _HomeKaderPageState extends State { onPressed: () { Navigator.pop(context); // Tutup dialog Navigator.pushNamedAndRemoveUntil( - context, - '/login', - (route) => false + context, + '/login', + (route) => false, ); }, - child: const Text( - 'Logout', - style: TextStyle(color: Colors.red), - ), + child: const Text('Logout', style: TextStyle(color: Colors.red)), ), ], ); }, ); } -} \ No newline at end of file +} diff --git a/lib/screens/kader/profile_page.dart b/lib/screens/kader/profile_page.dart index f8829c9..dff36e7 100644 --- a/lib/screens/kader/profile_page.dart +++ b/lib/screens/kader/profile_page.dart @@ -79,6 +79,9 @@ class _ProfilePageState extends State { var response = await request.send(); if (response.statusCode == 200) { + setState(() { + _imageFile = null; // reset biar ambil dari server + }); getProfile(); } } @@ -89,6 +92,13 @@ class _ProfilePageState extends State { getProfile(); } + // 🔥 Tambahan supaya refresh saat balik ke halaman ini + @override + void didChangeDependencies() { + super.didChangeDependencies(); + getProfile(); + } + @override Widget build(BuildContext context) { if (isLoading) { @@ -119,8 +129,12 @@ class _ProfilePageState extends State { backgroundImage: _imageFile != null ? FileImage(File(_imageFile!.path)) : user!['photo_url'] != null - ? NetworkImage(user!['photo_url']) - : null, + // 🔥 CACHE BUSTER DI SINI + ? NetworkImage( + user!['photo_url'] + + "?t=${DateTime.now().millisecondsSinceEpoch}", + ) + : null, child: user!['photo_url'] == null && _imageFile == null ? const Icon(Icons.person, size: 60) : null, @@ -206,4 +220,4 @@ class _ProfilePageState extends State { ), ); } -} +} \ No newline at end of file diff --git a/lib/screens/kader/reports_page.dart b/lib/screens/kader/reports_page.dart index 7ee31a5..d470ae4 100644 --- a/lib/screens/kader/reports_page.dart +++ b/lib/screens/kader/reports_page.dart @@ -1,9 +1,15 @@ import 'package:flutter/material.dart'; import 'add_report.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class ReportsPage extends StatelessWidget { const ReportsPage({super.key}); + Future getUserId() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getInt('id') ?? 0; + } + @override Widget build(BuildContext context) { return Padding( @@ -28,7 +34,7 @@ class ReportsPage extends StatelessWidget { ), ), const SizedBox(height: 30), - + // Card Panduan Container( padding: const EdgeInsets.all(20), @@ -73,19 +79,25 @@ class ReportsPage extends StatelessWidget { ], ), ), - + const SizedBox(height: 30), - + // Tombol Mulai SizedBox( width: double.infinity, height: 50, child: ElevatedButton.icon( - onPressed: () { + onPressed: () async { + int userId = await getUserId(); + + print("USER ID: $userId"); // debug + Navigator.push( context, MaterialPageRoute( - builder: (context) => const AddReportPage(), + builder: (context) => AddReportPage( + userId: userId, // ✅ FIX DI SINI + ), ), ); }, diff --git a/lib/screens/petugas/daftarkader.dart b/lib/screens/petugas/daftarkader.dart index 9085740..14509f5 100644 --- a/lib/screens/petugas/daftarkader.dart +++ b/lib/screens/petugas/daftarkader.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:sijentik/component/app_theme.dart'; +import 'package:sijentik/api/api.dart'; class DaftarKaderPage extends StatefulWidget { const DaftarKaderPage({super.key}); @@ -14,8 +15,6 @@ class _DaftarKaderPageState extends State { List kaderList = []; bool isLoading = true; - final String baseUrl = "http://192.168.1.6:8000/api"; - @override void initState() { super.initState(); @@ -25,6 +24,9 @@ class _DaftarKaderPageState extends State { Future fetchKader() async { final response = await http.get(Uri.parse("$baseUrl/users/kader")); + print("STATUS: ${response.statusCode}"); + print("BODY: ${response.body}"); + if (response.statusCode == 200) { final data = json.decode(response.body); @@ -35,109 +37,65 @@ class _DaftarKaderPageState extends State { } } - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: AppColors.button, - title: const Text("Daftar Kader"), - ), + Future deleteKader(int id) async { + final response = await http.delete(Uri.parse("$baseUrl/users/$id")); - body: isLoading - ? const Center(child: CircularProgressIndicator()) - : ListView.builder( - padding: const EdgeInsets.all(16), - itemCount: kaderList.length, - itemBuilder: (context, index) { - final kader = kaderList[index]; - return buildKaderCard(kader); - }, - ), - ); + if (response.statusCode == 200) { + fetchKader(); + + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text("Kader berhasil dihapus"))); + } else { + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text("Gagal menghapus kader"))); + } } - Widget buildKaderCard(dynamic kader) { - return Card( - margin: const EdgeInsets.only(bottom: 16), - child: Padding( - padding: const EdgeInsets.all(16), - - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - CircleAvatar(child: Text(kader['name'][0])), - - const SizedBox(width: 12), - - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - kader['name'], - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - - const SizedBox(height: 4), - - Text( - kader['email'], - style: const TextStyle(color: Colors.grey), - ), - ], - ), - ), - - IconButton( - icon: const Icon(Icons.edit), - onPressed: () { - showEditDialog(kader); - }, - ), - ], + void showDeleteDialog(dynamic kader) { + showDialog( + context: context, + builder: (_) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + title: const Text("Hapus Kader"), + content: Text("Yakin ingin menghapus ${kader['name']}?"), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("Batal"), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), ), - - const SizedBox(height: 12), - - Row( - children: [ - const Icon(Icons.location_on, size: 16), - const SizedBox(width: 5), - - Text("RT/RW : ${kader['rtrw']}"), - ], - ), - - const SizedBox(height: 5), - - Text("Alamat : ${kader['address']}"), - ], - ), + onPressed: () async { + Navigator.pop(context); + await deleteKader(kader['id']); + }, + child: const Text("Hapus"), + ), + ], ), ); } void showEditDialog(dynamic kader) { TextEditingController name = TextEditingController(text: kader['name']); - TextEditingController email = TextEditingController(text: kader['email']); - TextEditingController address = TextEditingController( text: kader['address'], ); - TextEditingController rtrw = TextEditingController(text: kader['rtrw']); showDialog( context: context, builder: (_) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), title: const Text("Edit Data Kader"), - content: SingleChildScrollView( child: Column( children: [ @@ -145,23 +103,17 @@ class _DaftarKaderPageState extends State { controller: name, decoration: const InputDecoration(labelText: "Nama"), ), - const SizedBox(height: 10), - TextField( controller: email, decoration: const InputDecoration(labelText: "Email"), ), - const SizedBox(height: 10), - TextField( controller: address, decoration: const InputDecoration(labelText: "Alamat"), ), - const SizedBox(height: 10), - TextField( controller: rtrw, decoration: const InputDecoration(labelText: "RT/RW"), @@ -169,13 +121,11 @@ class _DaftarKaderPageState extends State { ], ), ), - actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text("Batal"), ), - ElevatedButton( onPressed: () async { await http.put( @@ -189,7 +139,6 @@ class _DaftarKaderPageState extends State { ); Navigator.pop(context); - fetchKader(); ScaffoldMessenger.of(context).showSnackBar( @@ -202,4 +151,166 @@ class _DaftarKaderPageState extends State { ), ); } + + Widget buildKaderCard(dynamic kader) { + return Container( + margin: const EdgeInsets.only(bottom: 15), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(18), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.08), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + CircleAvatar( + radius: 26, + backgroundColor: AppColors.button, + child: ClipOval( + child: + kader['profile_photo'] != null && + kader['profile_photo'].toString().isNotEmpty + ? Image.network( + baseImageurl + kader['profile_photo'], + width: 52, + height: 52, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + print("ERROR IMAGE: $error"); + return Text( + kader['name'][0].toUpperCase(), + style: const TextStyle(color: Colors.white), + ); + }, + ) + : Text( + kader['name'][0].toUpperCase(), + style: const TextStyle(color: Colors.white), + ), + ), + ), + + const SizedBox(width: 12), + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + kader['name'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 3), + Text( + kader['email'], + style: TextStyle(color: Colors.grey[600]), + ), + ], + ), + ), + + Row( + children: [ + IconButton( + icon: const Icon(Icons.edit, color: Colors.blue), + onPressed: () => showEditDialog(kader), + ), + IconButton( + icon: const Icon(Icons.delete, color: Colors.red), + onPressed: () => showDeleteDialog(kader), + ), + ], + ), + ], + ), + + const SizedBox(height: 12), + + Row( + children: [ + const Icon(Icons.home, size: 16, color: Colors.grey), + const SizedBox(width: 6), + Text("RT/RW: ${kader['rtrw']}"), + ], + ), + + const SizedBox(height: 6), + + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon(Icons.location_on, size: 16, color: Colors.grey), + const SizedBox(width: 6), + Expanded( + child: Text( + kader['address'], + style: const TextStyle(fontSize: 13), + ), + ), + ], + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFFF4F7FB), + appBar: AppBar( + elevation: 0, + backgroundColor: AppColors.button, + title: const Text( + "Daftar Kader", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), + ), + ), + body: isLoading + ? const Center(child: CircularProgressIndicator()) + : Column( + children: [ + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColors.button, + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + ), + child: Text( + "Total Kader: ${kaderList.length}", + style: const TextStyle(color: Colors.white, fontSize: 16), + ), + ), + + const SizedBox(height: 10), + + Expanded( + child: ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: kaderList.length, + itemBuilder: (context, index) { + return buildKaderCard(kaderList[index]); + }, + ), + ), + ], + ), + ); + } } diff --git a/lib/screens/petugas/dashboardpetugas.dart b/lib/screens/petugas/dashboardpetugas.dart index 189b229..617203d 100644 --- a/lib/screens/petugas/dashboardpetugas.dart +++ b/lib/screens/petugas/dashboardpetugas.dart @@ -183,8 +183,8 @@ class _DashboardPetugasState extends State { children: [ const CircleAvatar( radius: 30, - backgroundColor: Colors.white, - child: Icon(Icons.person, size: 30, color: Colors.deepPurple), + backgroundColor: AppColors.button, + backgroundImage: AssetImage('assets/images/logo_petugas.png'), ), const SizedBox(width: 16), const Expanded( diff --git a/lib/screens/petugas/laporanpetugas.dart b/lib/screens/petugas/laporanpetugas.dart index c6dc902..1f0d118 100644 --- a/lib/screens/petugas/laporanpetugas.dart +++ b/lib/screens/petugas/laporanpetugas.dart @@ -2,6 +2,8 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; +import 'package:sijentik/api/api.dart'; +import 'package:sijentik/component/app_theme.dart'; class LaporanPetugasPage extends StatefulWidget { const LaporanPetugasPage({super.key}); @@ -11,7 +13,6 @@ class LaporanPetugasPage extends StatefulWidget { } class _LaporanPetugasPageState extends State { - static const String baseUrl = 'http://192.168.1.6:8000/api'; List laporanList = []; bool isLoading = false; @@ -217,8 +218,14 @@ class _LaporanPetugasPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Laporan Petugas'), - backgroundColor: Colors.blue, + title: const Text( + 'Laporan Petugas', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + backgroundColor: AppColors.button, ), body: Column( children: [ diff --git a/lib/screens/petugas/verifikasikader.dart b/lib/screens/petugas/verifikasikader.dart index 8fcb98f..423678d 100644 --- a/lib/screens/petugas/verifikasikader.dart +++ b/lib/screens/petugas/verifikasikader.dart @@ -1,7 +1,9 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:sijentik/api/api.dart' as Api; import 'package:sijentik/component/app_theme.dart'; +import 'package:sijentik/api/api.dart'; class VerifikasiKaderPage extends StatefulWidget { const VerifikasiKaderPage({super.key}); @@ -11,129 +13,103 @@ class VerifikasiKaderPage extends StatefulWidget { } class _VerifikasiKaderPageState extends State { - List kaderList = []; bool isLoadingList = false; - static const String baseUrl = 'http://192.168.1.6:8000/api'; - @override void initState() { super.initState(); fetchKader(); } - // ========================= - // FETCH KADER PENDING - // ========================= - Future fetchKader() async { + // FETCH KADER + Future fetchKader() async { + if (!mounted) return; setState(() => isLoadingList = true); try { - final response = await http.get( - Uri.parse('$baseUrl/kader/pending'), + Uri.parse("${Api.baseUrl}/kader/pending"), headers: {'Accept': 'application/json'}, ); + final data = jsonDecode(response.body); + + if (!mounted) return; + if (response.statusCode == 200) { - - final data = jsonDecode(response.body); - setState(() { kaderList = data['data']; }); - } else { - - final data = jsonDecode(response.body); - _showMessage(data['message'] ?? 'Gagal mengambil data'); - + _showMessage(data['message'] ?? 'Gagal mengambil data', success: false); } - } catch (e) { - - _showMessage('Error: $e'); - + if (!mounted) return; + _showMessage('Error: $e', success: false); } finally { - + if (!mounted) return; setState(() => isLoadingList = false); - } - } - // ========================= - // TERIMA KADER - // ========================= + // APPROVE + Future approveKader(int id) async { - try { - final response = await http.post( - Uri.parse('$baseUrl/kader/approve/$id'), + Uri.parse("${Api.baseUrl}/kader/approve/$id"), headers: {'Accept': 'application/json'}, ); final data = jsonDecode(response.body); - if (response.statusCode == 200) { + if (!mounted) return; + if (response.statusCode == 200) { _showMessage(data['message'] ?? 'Kader diterima'); fetchKader(); - } else { - - _showMessage(data['message'] ?? 'Gagal menerima kader'); - + _showMessage(data['message'] ?? 'Gagal menerima kader', success: false); } - } catch (e) { - - _showMessage('Error: $e'); - + if (!mounted) return; + _showMessage('Error: $e', success: false); } - } // ========================= - // TOLAK KADER + // REJECT // ========================= Future rejectKader(int id) async { - try { - final response = await http.post( - Uri.parse('$baseUrl/kader/reject/$id'), + Uri.parse("${Api.baseUrl}/kader/reject/$id"), headers: {'Accept': 'application/json'}, ); final data = jsonDecode(response.body); - if (response.statusCode == 200) { + if (!mounted) return; + if (response.statusCode == 200) { _showMessage(data['message'] ?? 'Kader ditolak'); fetchKader(); - } else { - - _showMessage(data['message'] ?? 'Gagal menolak kader'); - + _showMessage(data['message'] ?? 'Gagal menolak kader', success: false); } - } catch (e) { - - _showMessage('Error: $e'); - + if (!mounted) return; + _showMessage('Error: $e', success: false); } - } // ========================= - // MESSAGE + // MESSAGE (ANTI ERROR) // ========================= void _showMessage(String message, {bool success = true}) { + if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -141,14 +117,12 @@ class _VerifikasiKaderPageState extends State { backgroundColor: success ? Colors.green : Colors.red, ), ); - } // ========================= - // LIST KADER + // UI LIST // ========================= Widget buildKaderList() { - if (isLoadingList) { return const Center(child: CircularProgressIndicator()); } @@ -161,20 +135,15 @@ class _VerifikasiKaderPageState extends State { padding: const EdgeInsets.all(16), itemCount: kaderList.length, itemBuilder: (context, index) { - final kader = kaderList[index]; return Card( margin: const EdgeInsets.symmetric(vertical: 8), - child: Padding( padding: const EdgeInsets.all(12), - child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( kader['name'] ?? '-', style: const TextStyle( @@ -182,30 +151,21 @@ class _VerifikasiKaderPageState extends State { fontSize: 16, ), ), - const SizedBox(height: 6), - Text('Email: ${kader['email'] ?? '-'}'), - Text('RT/RW: ${kader['rtrw'] ?? '-'}'), - const SizedBox(height: 6), - Text('Alamat: ${kader['address'] ?? '-'}'), - const SizedBox(height: 12), Row( children: [ - Expanded( child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, ), - onPressed: () => approveKader(kader['id']), - child: const Text( 'Terima', style: TextStyle(color: Colors.white), @@ -220,41 +180,35 @@ class _VerifikasiKaderPageState extends State { style: ElevatedButton.styleFrom( backgroundColor: Colors.red, ), - onPressed: () => rejectKader(kader['id']), - child: const Text( 'Tolak', style: TextStyle(color: Colors.white), ), ), ), - ], ), - ], ), ), ); - }, ); } @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Verifikasi Kader'), + title: const Text( + 'Verifikasi Kader', + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), + ), + backgroundColor: AppColors.button, ), - body: buildKaderList(), - ); - } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index b1a0717..e628bb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -66,6 +66,7 @@ flutter: uses-material-design: true assets: - assets/images/ + - assets/images/logo_petugas.png # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg