Hapus modul dashboard dan home yang tidak digunakan
- Hapus file-file terkait dashboard untuk warga, donatur, dan petugas verifikasi - Hapus modul home yang sudah tidak diperlukan - Perbarui app_pages.dart untuk menghapus rute dashboard dan home - Bersihkan impor dan binding yang tidak digunakan
This commit is contained in:
@ -1,11 +0,0 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/controllers/dashboard_controller.dart';
|
|
||||||
|
|
||||||
class DashboardBinding extends Bindings {
|
|
||||||
@override
|
|
||||||
void dependencies() {
|
|
||||||
Get.lazyPut<DashboardController>(
|
|
||||||
() => DashboardController(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/data/models/user_model.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
|
||||||
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
|
||||||
|
|
||||||
class DashboardController extends GetxController {
|
|
||||||
final AuthController _authController = Get.find<AuthController>();
|
|
||||||
final SupabaseService _supabaseService = SupabaseService.to;
|
|
||||||
|
|
||||||
final RxBool isLoading = false.obs;
|
|
||||||
final Rx<Map<String, dynamic>?> roleData = Rx<Map<String, dynamic>?>(null);
|
|
||||||
|
|
||||||
// Indeks kategori yang dipilih untuk filter
|
|
||||||
final RxInt selectedCategoryIndex = 0.obs;
|
|
||||||
|
|
||||||
UserModel? get user => _authController.user;
|
|
||||||
String get role => user?.role ?? 'WARGA';
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onInit() {
|
|
||||||
super.onInit();
|
|
||||||
loadRoleData();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> loadRoleData() async {
|
|
||||||
isLoading.value = true;
|
|
||||||
try {
|
|
||||||
if (user != null) {
|
|
||||||
final data = await _supabaseService.getRoleSpecificData(role);
|
|
||||||
roleData.value = data;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
print('Error loading role data: $e');
|
|
||||||
} finally {
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void logout() {
|
|
||||||
_authController.logout();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,229 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/controllers/dashboard_controller.dart';
|
|
||||||
|
|
||||||
class DonaturDashboardView extends GetView<DashboardController> {
|
|
||||||
const DonaturDashboardView({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Dashboard Donatur'),
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: controller.logout,
|
|
||||||
tooltip: 'Logout',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: Obx(() {
|
|
||||||
if (controller.isLoading.value) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Greeting
|
|
||||||
Text(
|
|
||||||
'Halo, ${controller.roleData.value?['namaLengkap'] ?? controller.user?.email ?? 'Donatur'}!',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
const Text(
|
|
||||||
'Selamat datang di Dashboard Donatur',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Donatur Data
|
|
||||||
if (controller.roleData.value != null) ...[
|
|
||||||
const Text(
|
|
||||||
'Data Donatur',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
_buildInfoRow(
|
|
||||||
'NIK', controller.roleData.value?['NIK'] ?? '-'),
|
|
||||||
_buildInfoRow('Nama',
|
|
||||||
controller.roleData.value?['namaLengkap'] ?? '-'),
|
|
||||||
_buildInfoRow('No. Telp',
|
|
||||||
controller.roleData.value?['noTelp'] ?? '-'),
|
|
||||||
_buildInfoRow('Email',
|
|
||||||
controller.roleData.value?['email'] ?? '-'),
|
|
||||||
_buildInfoRow(
|
|
||||||
'Alamat',
|
|
||||||
controller.roleData.value?['alamatLengkap'] ??
|
|
||||||
'-'),
|
|
||||||
_buildInfoRow('Desa',
|
|
||||||
controller.roleData.value?['namaDesa'] ?? '-'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
] else ...[
|
|
||||||
const Center(
|
|
||||||
child: Text(
|
|
||||||
'Data donatur belum tersedia',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Menu
|
|
||||||
const Text(
|
|
||||||
'Menu',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Penitipan Bantuan',
|
|
||||||
'Titipkan bantuan Anda',
|
|
||||||
Icons.card_giftcard,
|
|
||||||
Colors.blue,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman penitipan bantuan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Riwayat Penitipan',
|
|
||||||
'Lihat riwayat penitipan bantuan',
|
|
||||||
Icons.history,
|
|
||||||
Colors.green,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman riwayat penitipan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Laporan Penyaluran',
|
|
||||||
'Lihat laporan penyaluran bantuan',
|
|
||||||
Icons.assessment,
|
|
||||||
Colors.orange,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman laporan penyaluran
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: () {
|
|
||||||
// Navigasi ke halaman penitipan bantuan baru
|
|
||||||
},
|
|
||||||
tooltip: 'Titipkan Bantuan Baru',
|
|
||||||
child: const Icon(Icons.add),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoRow(String label, String value) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 8.0),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 120,
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(value),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMenuCard(String title, String subtitle, IconData icon,
|
|
||||||
Color color, VoidCallback onTap) {
|
|
||||||
return Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color.withAlpha(26),
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
icon,
|
|
||||||
color: color,
|
|
||||||
size: 30,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
subtitle,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Icon(Icons.arrow_forward_ios, size: 16),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,216 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/controllers/dashboard_controller.dart';
|
|
||||||
|
|
||||||
class PetugasVerifikasiDashboardView extends GetView<DashboardController> {
|
|
||||||
const PetugasVerifikasiDashboardView({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Dashboard Petugas Verifikasi'),
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: controller.logout,
|
|
||||||
tooltip: 'Logout',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: Obx(() {
|
|
||||||
if (controller.isLoading.value) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Greeting
|
|
||||||
Text(
|
|
||||||
'Halo, ${controller.roleData.value?['namaLengkap'] ?? controller.user?.email ?? 'Petugas'}!',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
const Text(
|
|
||||||
'Selamat datang di Dashboard Petugas Verifikasi',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Petugas Data
|
|
||||||
if (controller.roleData.value != null) ...[
|
|
||||||
const Text(
|
|
||||||
'Data Petugas',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
_buildInfoRow(
|
|
||||||
'NIP', controller.roleData.value?['nip'] ?? '-'),
|
|
||||||
_buildInfoRow('Nama',
|
|
||||||
controller.roleData.value?['namaLengkap'] ?? '-'),
|
|
||||||
_buildInfoRow('Jabatan',
|
|
||||||
controller.roleData.value?['jabatan'] ?? '-'),
|
|
||||||
_buildInfoRow('Email',
|
|
||||||
controller.roleData.value?['email'] ?? '-'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
] else ...[
|
|
||||||
const Center(
|
|
||||||
child: Text(
|
|
||||||
'Data petugas belum tersedia',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Menu
|
|
||||||
const Text(
|
|
||||||
'Menu',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Verifikasi Data Warga',
|
|
||||||
'Verifikasi data warga baru',
|
|
||||||
Icons.verified_user,
|
|
||||||
Colors.blue,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman verifikasi data warga
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Verifikasi Pengajuan Bantuan',
|
|
||||||
'Verifikasi pengajuan bantuan',
|
|
||||||
Icons.fact_check,
|
|
||||||
Colors.green,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman verifikasi pengajuan bantuan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Kelola Skema Bantuan',
|
|
||||||
'Kelola skema bantuan yang tersedia',
|
|
||||||
Icons.settings,
|
|
||||||
Colors.orange,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman kelola skema bantuan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoRow(String label, String value) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 8.0),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 120,
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(value),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMenuCard(String title, String subtitle, IconData icon,
|
|
||||||
Color color, VoidCallback onTap) {
|
|
||||||
return Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color.withAlpha(26),
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
icon,
|
|
||||||
color: color,
|
|
||||||
size: 30,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
subtitle,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Icon(Icons.arrow_forward_ios, size: 16),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,295 +1 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/controllers/dashboard_controller.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
|
||||||
|
|
||||||
class WargaDashboardView extends GetView<DashboardController> {
|
|
||||||
const WargaDashboardView({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final authController = Get.find<AuthController>();
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Dashboard Warga'),
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: controller.logout,
|
|
||||||
tooltip: 'Logout',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: Obx(() {
|
|
||||||
if (controller.isLoading.value) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Greeting
|
|
||||||
Text(
|
|
||||||
'Halo, ${controller.user?.email ?? 'Pengguna'}!',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
const Text(
|
|
||||||
'Selamat datang di Dashboard Warga',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
|
|
||||||
// Status Profil
|
|
||||||
Obx(() => authController.isWargaProfileComplete.value
|
|
||||||
? _buildProfileCompleteCard()
|
|
||||||
: _buildProfileIncompleteCard(authController)),
|
|
||||||
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Warga Data
|
|
||||||
if (controller.roleData.value != null) ...[
|
|
||||||
const Text(
|
|
||||||
'Data Pribadi',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
_buildInfoRow('NIK',
|
|
||||||
controller.roleData.value?['NIK'] ?? '-'),
|
|
||||||
_buildInfoRow(
|
|
||||||
'Nama',
|
|
||||||
controller.roleData.value?['namaLengkap'] ??
|
|
||||||
'-'),
|
|
||||||
_buildInfoRow(
|
|
||||||
'Jenis Kelamin',
|
|
||||||
controller.roleData.value?['jenisKelamin'] ??
|
|
||||||
'-'),
|
|
||||||
_buildInfoRow('No. HP',
|
|
||||||
controller.roleData.value?['noHp'] ?? '-'),
|
|
||||||
_buildInfoRow('Alamat',
|
|
||||||
controller.roleData.value?['alamat'] ?? '-'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
] else ...[
|
|
||||||
const Center(
|
|
||||||
child: Text(
|
|
||||||
'Data warga belum tersedia',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Menu
|
|
||||||
const Text(
|
|
||||||
'Menu',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Pengajuan Bantuan',
|
|
||||||
'Ajukan permohonan bantuan',
|
|
||||||
Icons.request_page,
|
|
||||||
Colors.blue,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman pengajuan bantuan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Pengaduan',
|
|
||||||
'Sampaikan pengaduan Anda',
|
|
||||||
Icons.report_problem,
|
|
||||||
Colors.orange,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman pengaduan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
_buildMenuCard(
|
|
||||||
'Status Bantuan',
|
|
||||||
'Lihat status bantuan Anda',
|
|
||||||
Icons.info,
|
|
||||||
Colors.green,
|
|
||||||
() {
|
|
||||||
// Navigasi ke halaman status bantuan
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Widget untuk menampilkan status profil lengkap
|
|
||||||
Widget _buildProfileCompleteCard() {
|
|
||||||
return Card(
|
|
||||||
color: Colors.green.shade50,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.check_circle, color: Colors.green.shade700),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
const Expanded(
|
|
||||||
child: Text(
|
|
||||||
'Profil Anda sudah lengkap',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.green,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Widget untuk menampilkan status profil belum lengkap dengan tombol
|
|
||||||
Widget _buildProfileIncompleteCard(AuthController authController) {
|
|
||||||
return Card(
|
|
||||||
color: Colors.orange.shade50,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.warning, color: Colors.orange.shade700),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
const Expanded(
|
|
||||||
child: Text(
|
|
||||||
'Profil Anda belum lengkap',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.orange,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
const Text(
|
|
||||||
'Lengkapi profil Anda untuk mengakses semua fitur aplikasi',
|
|
||||||
style: TextStyle(fontSize: 12),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInfoRow(String label, String value) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 8.0),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 120,
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(value),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMenuCard(String title, String subtitle, IconData icon,
|
|
||||||
Color color, VoidCallback onTap) {
|
|
||||||
return Card(
|
|
||||||
elevation: 2,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: color.withAlpha(26),
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
icon,
|
|
||||||
color: color,
|
|
||||||
size: 30,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
subtitle,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Icon(Icons.arrow_forward_ios, size: 16),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/home/controllers/home_controller.dart';
|
|
||||||
|
|
||||||
class HomeBinding extends Bindings {
|
|
||||||
@override
|
|
||||||
void dependencies() {
|
|
||||||
Get.lazyPut<HomeController>(
|
|
||||||
() => HomeController(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
|
||||||
|
|
||||||
class HomeController extends GetxController {
|
|
||||||
final AuthController _authController = Get.find<AuthController>();
|
|
||||||
|
|
||||||
// Getter untuk mendapatkan user dari auth controller
|
|
||||||
get user => _authController.user;
|
|
||||||
|
|
||||||
// Metode untuk logout
|
|
||||||
void logout() {
|
|
||||||
_authController.logout();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/home/controllers/home_controller.dart';
|
|
||||||
|
|
||||||
class HomeView extends GetView<HomeController> {
|
|
||||||
const HomeView({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Penyaluran App'),
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: controller.logout,
|
|
||||||
tooltip: 'Logout',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// Greeting
|
|
||||||
Text(
|
|
||||||
'Halo, ${controller.user?.email ?? 'Pengguna'}!',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
const Text(
|
|
||||||
'Selamat datang di Penyaluran App',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
|
|
||||||
// Dashboard Content
|
|
||||||
const Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
'Halaman Dashboard',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_controller.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/routes/app_pages.dart';
|
||||||
|
|
||||||
class JadwalSectionWidget extends StatelessWidget {
|
class JadwalSectionWidget extends StatelessWidget {
|
||||||
final PetugasDesaController controller;
|
final PetugasDesaController controller;
|
||||||
@ -90,7 +91,12 @@ class JadwalSectionWidget extends StatelessWidget {
|
|||||||
statusColor = Colors.orange;
|
statusColor = Colors.orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// Navigasi ke halaman pelaksanaan penyaluran dengan data jadwal
|
||||||
|
Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwal);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
margin: const EdgeInsets.only(bottom: 10),
|
margin: const EdgeInsets.only(bottom: 10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -158,8 +164,28 @@ class JadwalSectionWidget extends StatelessWidget {
|
|||||||
style: textTheme.bodyMedium,
|
style: textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Lihat Detail',
|
||||||
|
style: textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.blue,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
const Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,431 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||||
|
|
||||||
|
class PelaksanaanPenyaluranView extends GetView<PetugasDesaController> {
|
||||||
|
const PelaksanaanPenyaluranView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Ambil data jadwal dari parameter
|
||||||
|
final jadwal = Get.arguments as Map<String, dynamic>;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Detail Pelaksanaan Penyaluran'),
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Header dengan informasi pelaksanaan
|
||||||
|
_buildHeaderInfo(context, jadwal),
|
||||||
|
|
||||||
|
// Daftar penerima bantuan
|
||||||
|
_buildDaftarPenerima(context, jadwal),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bottomNavigationBar: _buildBottomButtons(context, jadwal),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHeaderInfo(BuildContext context, Map<String, dynamic> jadwal) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: AppTheme.primaryGradient,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
jadwal['lokasi'] ?? 'Lokasi Penyaluran',
|
||||||
|
style: textTheme.headlineSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildInfoItem(context,
|
||||||
|
icon: Icons.category,
|
||||||
|
label: 'Jenis Bantuan',
|
||||||
|
value: jadwal['jenis_bantuan'] ?? '-'),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildInfoItem(context,
|
||||||
|
icon: Icons.calendar_today,
|
||||||
|
label: 'Tanggal',
|
||||||
|
value: jadwal['tanggal'] ?? '-'),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildInfoItem(context,
|
||||||
|
icon: Icons.access_time,
|
||||||
|
label: 'Waktu',
|
||||||
|
value: jadwal['waktu'] ?? '-'),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildInfoItem(context,
|
||||||
|
icon: Icons.people,
|
||||||
|
label: 'Jumlah Penerima',
|
||||||
|
value: '${jadwal['jumlah_penerima'] ?? 0} orang'),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildInfoItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.flag,
|
||||||
|
label: 'Status',
|
||||||
|
value: jadwal['status'] ?? 'Aktif',
|
||||||
|
isStatus: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoItem(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
bool isStatus = false,
|
||||||
|
}) {
|
||||||
|
Color statusColor = Colors.white;
|
||||||
|
if (isStatus) {
|
||||||
|
switch (value.toLowerCase()) {
|
||||||
|
case 'aktif':
|
||||||
|
statusColor = Colors.green;
|
||||||
|
break;
|
||||||
|
case 'terjadwal':
|
||||||
|
statusColor = Colors.blue;
|
||||||
|
break;
|
||||||
|
case 'selesai':
|
||||||
|
statusColor = Colors.grey;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusColor = Colors.orange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'$label: ',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: isStatus ? statusColor : Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDaftarPenerima(
|
||||||
|
BuildContext context, Map<String, dynamic> jadwal) {
|
||||||
|
// Simulasi data penerima bantuan
|
||||||
|
final List<Map<String, dynamic>> daftarPenerima = [
|
||||||
|
{
|
||||||
|
'id': '1',
|
||||||
|
'nama': 'Ahmad Sulaiman',
|
||||||
|
'nik': '3201234567890001',
|
||||||
|
'alamat': 'Dusun Sukamaju RT 02/03',
|
||||||
|
'status': 'belum_diterima',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '2',
|
||||||
|
'nama': 'Siti Aminah',
|
||||||
|
'nik': '3201234567890002',
|
||||||
|
'alamat': 'Dusun Sukamaju RT 01/03',
|
||||||
|
'status': 'sudah_diterima',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '3',
|
||||||
|
'nama': 'Budi Santoso',
|
||||||
|
'nik': '3201234567890003',
|
||||||
|
'alamat': 'Dusun Sukamaju RT 03/01',
|
||||||
|
'status': 'belum_diterima',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '4',
|
||||||
|
'nama': 'Dewi Lestari',
|
||||||
|
'nik': '3201234567890004',
|
||||||
|
'alamat': 'Dusun Sukamaju RT 04/02',
|
||||||
|
'status': 'sudah_diterima',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '5',
|
||||||
|
'nama': 'Joko Widodo',
|
||||||
|
'nik': '3201234567890005',
|
||||||
|
'alamat': 'Dusun Sukamaju RT 05/01',
|
||||||
|
'status': 'belum_diterima',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Daftar Penerima Bantuan',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${daftarPenerima.length} orang',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Colors.grey.shade600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Search bar
|
||||||
|
TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Cari penerima...',
|
||||||
|
prefixIcon: const Icon(Icons.search),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
borderSide: BorderSide(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
borderSide: BorderSide(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.grey.shade50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Filter status
|
||||||
|
SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
_buildFilterChip(context, 'Semua', true),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
_buildFilterChip(context, 'Sudah Diterima', false),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
_buildFilterChip(context, 'Belum Diterima', false),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Daftar penerima
|
||||||
|
...daftarPenerima
|
||||||
|
.map((penerima) => _buildPenerimaItem(context, penerima))
|
||||||
|
.toList(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildFilterChip(BuildContext context, String label, bool isSelected) {
|
||||||
|
return FilterChip(
|
||||||
|
label: Text(label),
|
||||||
|
selected: isSelected,
|
||||||
|
onSelected: (selected) {
|
||||||
|
// Implementasi filter
|
||||||
|
},
|
||||||
|
backgroundColor: Colors.grey.shade100,
|
||||||
|
selectedColor: AppTheme.primaryColor.withOpacity(0.2),
|
||||||
|
checkmarkColor: AppTheme.primaryColor,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: isSelected ? AppTheme.primaryColor : Colors.black,
|
||||||
|
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPenerimaItem(
|
||||||
|
BuildContext context, Map<String, dynamic> penerima) {
|
||||||
|
final bool sudahDiterima = penerima['status'] == 'sudah_diterima';
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withAlpha(26),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 3,
|
||||||
|
offset: const Offset(0, 1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
title: Text(
|
||||||
|
penerima['nama'] ?? '',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text('NIK: ${penerima['nik'] ?? ''}'),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
Text('Alamat: ${penerima['alamat'] ?? ''}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
trailing: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: sudahDiterima
|
||||||
|
? Colors.green.withAlpha(26)
|
||||||
|
: Colors.orange.withAlpha(26),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
sudahDiterima ? 'Sudah Diterima' : 'Belum Diterima',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: sudahDiterima ? Colors.green : Colors.orange,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
// Navigasi ke halaman konfirmasi penerima
|
||||||
|
Get.toNamed(
|
||||||
|
'/daftar-penerima/konfirmasi',
|
||||||
|
arguments: penerima['id'],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBottomButtons(
|
||||||
|
BuildContext context, Map<String, dynamic> jadwal) {
|
||||||
|
final bool isSelesai = (jadwal['status'] ?? '').toLowerCase() == 'selesai';
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withAlpha(50),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: const Offset(0, -1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: isSelesai
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
// Implementasi cetak laporan
|
||||||
|
Get.snackbar(
|
||||||
|
'Informasi',
|
||||||
|
'Mencetak laporan penyaluran...',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.print),
|
||||||
|
label: const Text('Cetak Laporan'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: isSelesai
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
// Implementasi selesaikan penyaluran
|
||||||
|
_showSelesaikanDialog(context, jadwal);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.check_circle),
|
||||||
|
label: const Text('Selesaikan'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: isSelesai ? Colors.grey : Colors.green,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showSelesaikanDialog(
|
||||||
|
BuildContext context, Map<String, dynamic> jadwal) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Selesaikan Penyaluran'),
|
||||||
|
content:
|
||||||
|
const Text('Apakah Anda yakin ingin menyelesaikan penyaluran ini? '
|
||||||
|
'Pastikan semua penerima telah dikonfirmasi.'),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Batal'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi selesaikan penyaluran
|
||||||
|
Navigator.pop(context);
|
||||||
|
Get.back(); // Kembali ke halaman sebelumnya
|
||||||
|
Get.snackbar(
|
||||||
|
'Berhasil',
|
||||||
|
'Penyaluran telah diselesaikan',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
colorText: Colors.white,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
),
|
||||||
|
child: const Text('Selesaikan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,13 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:penyaluran_app/app/modules/auth/views/login_view.dart';
|
import 'package:penyaluran_app/app/modules/auth/views/login_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/home/views/home_view.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/views/warga_dashboard_view.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/views/petugas_verifikasi_dashboard_view.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/views/donatur_dashboard_view.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/auth/bindings/auth_binding.dart';
|
import 'package:penyaluran_app/app/modules/auth/bindings/auth_binding.dart';
|
||||||
import 'package:penyaluran_app/app/modules/home/bindings/home_binding.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/dashboard/bindings/dashboard_binding.dart';
|
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/petugas_desa_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/petugas_desa_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/bindings/petugas_desa_binding.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/bindings/petugas_desa_binding.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/permintaan_penjadwalan_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/permintaan_penjadwalan_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/daftar_penerima_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/daftar_penerima_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/detail_penerima_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/detail_penerima_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/pelaksanaan_penyaluran_view.dart';
|
||||||
|
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/bindings/penerima_binding.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/bindings/penerima_binding.dart';
|
||||||
|
|
||||||
@ -24,36 +19,16 @@ class AppPages {
|
|||||||
static const initial = Routes.login;
|
static const initial = Routes.login;
|
||||||
|
|
||||||
static final routes = [
|
static final routes = [
|
||||||
GetPage(
|
|
||||||
name: _Paths.home,
|
|
||||||
page: () => const HomeView(),
|
|
||||||
binding: HomeBinding(),
|
|
||||||
),
|
|
||||||
GetPage(
|
GetPage(
|
||||||
name: _Paths.login,
|
name: _Paths.login,
|
||||||
page: () => const LoginView(),
|
page: () => const LoginView(),
|
||||||
binding: AuthBinding(),
|
binding: AuthBinding(),
|
||||||
),
|
),
|
||||||
GetPage(
|
|
||||||
name: _Paths.wargaDashboard,
|
|
||||||
page: () => const WargaDashboardView(),
|
|
||||||
binding: DashboardBinding(),
|
|
||||||
),
|
|
||||||
GetPage(
|
|
||||||
name: _Paths.petugasVerifikasiDashboard,
|
|
||||||
page: () => const PetugasVerifikasiDashboardView(),
|
|
||||||
binding: DashboardBinding(),
|
|
||||||
),
|
|
||||||
GetPage(
|
GetPage(
|
||||||
name: _Paths.petugasDesaDashboard,
|
name: _Paths.petugasDesaDashboard,
|
||||||
page: () => const PetugasDesaView(),
|
page: () => const PetugasDesaView(),
|
||||||
binding: PetugasDesaBinding(),
|
binding: PetugasDesaBinding(),
|
||||||
),
|
),
|
||||||
GetPage(
|
|
||||||
name: _Paths.donaturDashboard,
|
|
||||||
page: () => const DonaturDashboardView(),
|
|
||||||
binding: DashboardBinding(),
|
|
||||||
),
|
|
||||||
GetPage(
|
GetPage(
|
||||||
name: _Paths.permintaanPenjadwalan,
|
name: _Paths.permintaanPenjadwalan,
|
||||||
page: () => const PermintaanPenjadwalanView(),
|
page: () => const PermintaanPenjadwalanView(),
|
||||||
@ -74,5 +49,10 @@ class AppPages {
|
|||||||
page: () => const KonfirmasiPenerimaView(),
|
page: () => const KonfirmasiPenerimaView(),
|
||||||
binding: PenerimaBinding(),
|
binding: PenerimaBinding(),
|
||||||
),
|
),
|
||||||
|
GetPage(
|
||||||
|
name: _Paths.pelaksanaanPenyaluran,
|
||||||
|
page: () => const PelaksanaanPenyaluranView(),
|
||||||
|
binding: PetugasDesaBinding(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ abstract class Routes {
|
|||||||
static const daftarPenerima = _Paths.daftarPenerima;
|
static const daftarPenerima = _Paths.daftarPenerima;
|
||||||
static const detailPenerima = _Paths.detailPenerima;
|
static const detailPenerima = _Paths.detailPenerima;
|
||||||
static const konfirmasiPenerima = _Paths.konfirmasiPenerima;
|
static const konfirmasiPenerima = _Paths.konfirmasiPenerima;
|
||||||
|
static const pelaksanaanPenyaluran = _Paths.pelaksanaanPenyaluran;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _Paths {
|
abstract class _Paths {
|
||||||
@ -30,4 +31,5 @@ abstract class _Paths {
|
|||||||
static const daftarPenerima = '/daftar-penerima';
|
static const daftarPenerima = '/daftar-penerima';
|
||||||
static const detailPenerima = '/daftar-penerima/detail';
|
static const detailPenerima = '/daftar-penerima/detail';
|
||||||
static const konfirmasiPenerima = '/daftar-penerima/konfirmasi';
|
static const konfirmasiPenerima = '/daftar-penerima/konfirmasi';
|
||||||
|
static const pelaksanaanPenyaluran = '/pelaksanaan-penyaluran';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user