Tambahkan fitur daftar penerima dan navigasi detail penerima
- Buat kontroler dan tampilan untuk daftar penerima - Tambahkan rute baru untuk daftar penerima dan detail penerima - Perbarui dashboard dengan navigasi ke daftar penerima - Tambahkan kemampuan untuk membuka detail penerima dari dashboard - Integrasikan fitur baru ke dalam drawer navigasi Petugas Desa
This commit is contained in:
12
lib/app/modules/petugas_desa/bindings/penerima_binding.dart
Normal file
12
lib/app/modules/petugas_desa/bindings/penerima_binding.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
|
||||||
|
class PenerimaBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut<PenerimaController>(
|
||||||
|
() => PenerimaController(),
|
||||||
|
fenix: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
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/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
|
||||||
class PetugasDesaBinding extends Bindings {
|
class PetugasDesaBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
@ -8,5 +9,8 @@ class PetugasDesaBinding extends Bindings {
|
|||||||
() => PetugasDesaController(),
|
() => PetugasDesaController(),
|
||||||
fenix: true,
|
fenix: true,
|
||||||
);
|
);
|
||||||
|
Get.lazyPut<PenerimaController>(
|
||||||
|
() => PenerimaController(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,152 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class PenerimaController extends GetxController {
|
||||||
|
final RxList<Map<String, dynamic>> daftarPenerima =
|
||||||
|
<Map<String, dynamic>>[].obs;
|
||||||
|
final RxBool isLoading = false.obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
fetchDaftarPenerima();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
// Pastikan data dimuat saat controller siap
|
||||||
|
if (daftarPenerima.isEmpty) {
|
||||||
|
fetchDaftarPenerima();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetchDaftarPenerima() {
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
|
// Simulasi data penerima
|
||||||
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
|
daftarPenerima.value = [
|
||||||
|
{
|
||||||
|
'id': '1',
|
||||||
|
'nama': 'Bagus Jayadi',
|
||||||
|
'nik': '3201020107030010',
|
||||||
|
'noKK': '3201020107030383',
|
||||||
|
'noHandphone': '089891256532',
|
||||||
|
'email': 'bgjayadi@gmail.com',
|
||||||
|
'jenisKelamin': 'Pria',
|
||||||
|
'agama': 'Islam',
|
||||||
|
'tempatTanggalLahir': 'Bogor, 2 Juni 1990',
|
||||||
|
'alamatLengkap':
|
||||||
|
'Jl. Leada Natsir No. 22 RT 001/003 Kec. Gunung Putri Kab. Bogor',
|
||||||
|
'pekerjaan': 'Petani',
|
||||||
|
'pendidikanTerakhir': 'Sekolah Dasar (SD)',
|
||||||
|
'status': 'Belum disalurkan',
|
||||||
|
'foto': 'assets/images/profile.jpg',
|
||||||
|
'terverifikasi': true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '2',
|
||||||
|
'nama': 'Siti Rahayu',
|
||||||
|
'nik': '3201020107030011',
|
||||||
|
'noKK': '3201020107030384',
|
||||||
|
'noHandphone': '089891256533',
|
||||||
|
'email': 'sitirahayu@gmail.com',
|
||||||
|
'jenisKelamin': 'Wanita',
|
||||||
|
'agama': 'Islam',
|
||||||
|
'tempatTanggalLahir': 'Bogor, 15 Agustus 1985',
|
||||||
|
'alamatLengkap':
|
||||||
|
'Jl. Raya Bogor No. 45 RT 002/004 Kec. Gunung Putri Kab. Bogor',
|
||||||
|
'pekerjaan': 'Ibu Rumah Tangga',
|
||||||
|
'pendidikanTerakhir': 'SMP',
|
||||||
|
'status': 'Selesai',
|
||||||
|
'foto': 'assets/images/profile.jpg',
|
||||||
|
'terverifikasi': true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '3',
|
||||||
|
'nama': 'Budi Santoso',
|
||||||
|
'nik': '3201020107030012',
|
||||||
|
'noKK': '3201020107030385',
|
||||||
|
'noHandphone': '089891256534',
|
||||||
|
'email': 'budisantoso@gmail.com',
|
||||||
|
'jenisKelamin': 'Pria',
|
||||||
|
'agama': 'Islam',
|
||||||
|
'tempatTanggalLahir': 'Jakarta, 10 Januari 1980',
|
||||||
|
'alamatLengkap':
|
||||||
|
'Jl. Merdeka No. 12 RT 003/005 Kec. Gunung Putri Kab. Bogor',
|
||||||
|
'pekerjaan': 'Buruh',
|
||||||
|
'pendidikanTerakhir': 'SMA',
|
||||||
|
'status': 'Selesai',
|
||||||
|
'foto': 'assets/images/profile.jpg',
|
||||||
|
'terverifikasi': true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '4',
|
||||||
|
'nama': 'Dewi Lestari',
|
||||||
|
'nik': '3201020107030013',
|
||||||
|
'noKK': '3201020107030386',
|
||||||
|
'noHandphone': '089891256535',
|
||||||
|
'email': 'dewilestari@gmail.com',
|
||||||
|
'jenisKelamin': 'Wanita',
|
||||||
|
'agama': 'Islam',
|
||||||
|
'tempatTanggalLahir': 'Bandung, 5 Mei 1992',
|
||||||
|
'alamatLengkap':
|
||||||
|
'Jl. Pahlawan No. 8 RT 004/006 Kec. Gunung Putri Kab. Bogor',
|
||||||
|
'pekerjaan': 'Guru',
|
||||||
|
'pendidikanTerakhir': 'S1',
|
||||||
|
'status': 'Selesai',
|
||||||
|
'foto': 'assets/images/profile.jpg',
|
||||||
|
'terverifikasi': true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '5',
|
||||||
|
'nama': 'Ahmad Fauzi',
|
||||||
|
'nik': '3201020107030014',
|
||||||
|
'noKK': '3201020107030387',
|
||||||
|
'noHandphone': '089891256536',
|
||||||
|
'email': 'ahmadfauzi@gmail.com',
|
||||||
|
'jenisKelamin': 'Pria',
|
||||||
|
'agama': 'Islam',
|
||||||
|
'tempatTanggalLahir': 'Surabaya, 20 Desember 1988',
|
||||||
|
'alamatLengkap':
|
||||||
|
'Jl. Sudirman No. 15 RT 005/007 Kec. Gunung Putri Kab. Bogor',
|
||||||
|
'pekerjaan': 'Wiraswasta',
|
||||||
|
'pendidikanTerakhir': 'SMA',
|
||||||
|
'status': 'Terjadwal',
|
||||||
|
'foto': 'assets/images/profile.jpg',
|
||||||
|
'terverifikasi': true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
isLoading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic>? getPenerimaById(String id) {
|
||||||
|
try {
|
||||||
|
if (daftarPenerima.isEmpty) {
|
||||||
|
// Jika data belum dimuat, muat data terlebih dahulu
|
||||||
|
fetchDaftarPenerima();
|
||||||
|
// Kembalikan data dummy sementara
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'nama': 'Memuat data...',
|
||||||
|
'nik': 'Memuat...',
|
||||||
|
'noKK': 'Memuat...',
|
||||||
|
'noHandphone': 'Memuat...',
|
||||||
|
'email': 'Memuat...',
|
||||||
|
'jenisKelamin': 'Memuat...',
|
||||||
|
'agama': 'Memuat...',
|
||||||
|
'tempatTanggalLahir': 'Memuat...',
|
||||||
|
'alamatLengkap': 'Memuat...',
|
||||||
|
'pekerjaan': 'Memuat...',
|
||||||
|
'pendidikanTerakhir': 'Memuat...',
|
||||||
|
'status': 'Memuat...',
|
||||||
|
'terverifikasi': false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return daftarPenerima.firstWhere((penerima) => penerima['id'] == id);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
316
lib/app/modules/petugas_desa/views/daftar_penerima_view.dart
Normal file
316
lib/app/modules/petugas_desa/views/daftar_penerima_view.dart
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||||
|
|
||||||
|
class DaftarPenerimaView extends GetView<PenerimaController> {
|
||||||
|
const DaftarPenerimaView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Daftar Penerima'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.search),
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi pencarian
|
||||||
|
showSearch(
|
||||||
|
context: context,
|
||||||
|
delegate: PenerimaSearchDelegate(controller.daftarPenerima),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Obx(() {
|
||||||
|
if (controller.isLoading.value) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller.daftarPenerima.isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: Text('Tidak ada data penerima'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
itemCount: controller.daftarPenerima.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final penerima = controller.daftarPenerima[index];
|
||||||
|
return _buildPenerimaCard(context, penerima);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPenerimaCard(
|
||||||
|
BuildContext context, Map<String, dynamic> penerima) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
|
elevation: 2,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
// Navigasi ke halaman detail penerima
|
||||||
|
Get.toNamed('/daftar-penerima/detail', arguments: penerima['id']);
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// Foto profil
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 30,
|
||||||
|
backgroundColor: AppTheme.primaryColor.withOpacity(0.1),
|
||||||
|
child: penerima['foto'] != null
|
||||||
|
? ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
child: Image.asset(
|
||||||
|
penerima['foto'],
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return const Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 30,
|
||||||
|
color: AppTheme.primaryColor,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 30,
|
||||||
|
color: AppTheme.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
// Informasi penerima
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
penerima['nama'] ?? '',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (penerima['terverifikasi'] == true)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.verified,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
const Text(
|
||||||
|
'Terverifikasi',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
'NIK: ${penerima['nik'] ?? ''}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// const SizedBox(height: 8),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// penerima['alamatLengkap'] ?? '',
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 12,
|
||||||
|
// color: Colors.grey[600],
|
||||||
|
// ),
|
||||||
|
// maxLines: 1,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
// ),
|
||||||
|
// _buildStatusBadge(penerima['status']),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusBadge(String? status) {
|
||||||
|
Color backgroundColor;
|
||||||
|
Color textColor;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case 'Selesai':
|
||||||
|
backgroundColor = Colors.green.withOpacity(0.1);
|
||||||
|
textColor = Colors.green;
|
||||||
|
break;
|
||||||
|
case 'Terjadwal':
|
||||||
|
backgroundColor = Colors.blue.withOpacity(0.1);
|
||||||
|
textColor = Colors.blue;
|
||||||
|
break;
|
||||||
|
case 'Belum disalurkan':
|
||||||
|
backgroundColor = Colors.orange.withOpacity(0.1);
|
||||||
|
textColor = Colors.orange;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
backgroundColor = Colors.grey.withOpacity(0.1);
|
||||||
|
textColor = Colors.grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: backgroundColor,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
status ?? 'Tidak diketahui',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PenerimaSearchDelegate extends SearchDelegate {
|
||||||
|
final List<Map<String, dynamic>> daftarPenerima;
|
||||||
|
|
||||||
|
PenerimaSearchDelegate(this.daftarPenerima);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Widget> buildActions(BuildContext context) {
|
||||||
|
return [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () {
|
||||||
|
query = '';
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildLeading(BuildContext context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
onPressed: () {
|
||||||
|
close(context, null);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildResults(BuildContext context) {
|
||||||
|
return _buildSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildSuggestions(BuildContext context) {
|
||||||
|
return _buildSearchResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSearchResults() {
|
||||||
|
final filteredList = daftarPenerima.where((penerima) {
|
||||||
|
final nama = penerima['nama']?.toString().toLowerCase() ?? '';
|
||||||
|
final nik = penerima['nik']?.toString().toLowerCase() ?? '';
|
||||||
|
final alamat = penerima['alamatLengkap']?.toString().toLowerCase() ?? '';
|
||||||
|
final searchLower = query.toLowerCase();
|
||||||
|
|
||||||
|
return nama.contains(searchLower) ||
|
||||||
|
nik.contains(searchLower) ||
|
||||||
|
alamat.contains(searchLower);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
if (filteredList.isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: Text('Tidak ada hasil yang ditemukan'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
itemCount: filteredList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final penerima = filteredList[index];
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
|
elevation: 2,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: ListTile(
|
||||||
|
onTap: () {
|
||||||
|
close(context, null);
|
||||||
|
Get.toNamed('/daftar-penerima/detail', arguments: penerima['id']);
|
||||||
|
},
|
||||||
|
leading: CircleAvatar(
|
||||||
|
backgroundColor: AppTheme.primaryColor.withOpacity(0.1),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.person,
|
||||||
|
color: AppTheme.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
penerima['nama'] ?? '',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text('NIK: ${penerima['nik'] ?? ''}'),
|
||||||
|
trailing: penerima['terverifikasi'] == true
|
||||||
|
? const Icon(
|
||||||
|
Icons.verified,
|
||||||
|
color: Colors.green,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import 'package:penyaluran_app/app/modules/petugas_desa/components/greeting_head
|
|||||||
import 'package:penyaluran_app/app/modules/petugas_desa/components/progress_section.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/components/progress_section.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/components/schedule_card.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/components/schedule_card.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/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||||
import 'package:penyaluran_app/app/widgets/statistic_card.dart';
|
import 'package:penyaluran_app/app/widgets/statistic_card.dart';
|
||||||
|
|
||||||
@ -114,7 +115,9 @@ class DashboardView extends GetView<PetugasDesaController> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
Get.toNamed('/daftar-penerima');
|
||||||
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
@ -135,11 +138,11 @@ class DashboardView extends GetView<PetugasDesaController> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
_buildRecipientItem(
|
_buildRecipientItem(
|
||||||
'Siti Rahayu', '3201020107030010', 'Selesai', textTheme),
|
'Siti Rahayu', '3201020107030011', 'Selesai', textTheme),
|
||||||
_buildRecipientItem(
|
_buildRecipientItem(
|
||||||
'Budi Santoso', '3201020107030011', 'Selesai', textTheme),
|
'Budi Santoso', '3201020107030012', 'Selesai', textTheme),
|
||||||
_buildRecipientItem(
|
_buildRecipientItem(
|
||||||
'Dewi Lestari', '3201020107030012', 'Selesai', textTheme),
|
'Dewi Lestari', '3201020107030013', 'Selesai', textTheme),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -153,31 +156,45 @@ class DashboardView extends GetView<PetugasDesaController> {
|
|||||||
gradient: AppTheme.primaryGradient,
|
gradient: AppTheme.primaryGradient,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: InkWell(
|
||||||
title: Text(
|
onTap: () {
|
||||||
name,
|
// Navigasi ke detail penerima dengan ID statis
|
||||||
style: textTheme.titleMedium?.copyWith(
|
// Kita gunakan ID 1 untuk Siti Rahayu, 2 untuk Budi Santoso, 3 untuk Dewi Lestari
|
||||||
fontWeight: FontWeight.bold,
|
String id = "1"; // Default
|
||||||
color: Colors.white,
|
if (nik == "3201020107030011") {
|
||||||
),
|
id = "2";
|
||||||
),
|
} else if (nik == "3201020107030012") {
|
||||||
subtitle: Text(
|
id = "3";
|
||||||
'NIK: $nik',
|
}
|
||||||
style: textTheme.bodyMedium?.copyWith(
|
Get.toNamed('/daftar-penerima/detail', arguments: id);
|
||||||
color: Colors.white,
|
},
|
||||||
),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
child: ListTile(
|
||||||
trailing: Container(
|
title: Text(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
name,
|
||||||
decoration: BoxDecoration(
|
style: textTheme.titleMedium?.copyWith(
|
||||||
color: Colors.white.withOpacity(0.2),
|
fontWeight: FontWeight.bold,
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
status,
|
|
||||||
style: textTheme.bodySmall?.copyWith(
|
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 12,
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
'NIK: $nik',
|
||||||
|
style: textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
status,
|
||||||
|
style: textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
434
lib/app/modules/petugas_desa/views/detail_penerima_view.dart
Normal file
434
lib/app/modules/petugas_desa/views/detail_penerima_view.dart
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||||
|
|
||||||
|
class DetailPenerimaView extends GetView<PenerimaController> {
|
||||||
|
const DetailPenerimaView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final String id = Get.arguments as String;
|
||||||
|
|
||||||
|
return Obx(() {
|
||||||
|
if (controller.isLoading.value) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Detail Penerima'),
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final penerima = controller.getPenerimaById(id);
|
||||||
|
|
||||||
|
if (penerima == null) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Detail Penerima'),
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text('Data penerima tidak ditemukan'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Detail Penerima'),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi edit penerima
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Header dengan foto dan nama
|
||||||
|
_buildHeader(penerima),
|
||||||
|
|
||||||
|
// Detail informasi penerima
|
||||||
|
_buildDetailInfo(penerima),
|
||||||
|
|
||||||
|
// Status penyaluran
|
||||||
|
_buildStatusSection(penerima),
|
||||||
|
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bottomNavigationBar: _buildBottomButtons(penerima),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHeader(Map<String, dynamic> penerima) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: AppTheme.primaryGradient,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// Foto profil
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 50,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
child: penerima['foto'] != null
|
||||||
|
? ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(50),
|
||||||
|
child: Image.asset(
|
||||||
|
penerima['foto'],
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return const Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 50,
|
||||||
|
color: AppTheme.primaryColor,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 50,
|
||||||
|
color: AppTheme.primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Nama penerima
|
||||||
|
Text(
|
||||||
|
penerima['nama'] ?? '',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
// NIK
|
||||||
|
Text(
|
||||||
|
penerima['nik'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.white.withOpacity(0.8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Badge terverifikasi
|
||||||
|
if (penerima['terverifikasi'] == true)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: const Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.verified,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Terverifikasi',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDetailInfo(Map<String, dynamic> penerima) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Detail Penerima',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Informasi detail dalam bentuk card
|
||||||
|
Card(
|
||||||
|
elevation: 2,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildInfoRow('NIK', penerima['nik'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('No KK', penerima['noKK'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('No Handphone', penerima['noHandphone'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('Email', penerima['email'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow(
|
||||||
|
'Jenis Kelamin', penerima['jenisKelamin'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('Agama', penerima['agama'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('Tempat, Tanggal Lahir',
|
||||||
|
penerima['tempatTanggalLahir'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow(
|
||||||
|
'Alamat Lengkap', penerima['alamatLengkap'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('Pekerjaan', penerima['pekerjaan'] ?? '-'),
|
||||||
|
const Divider(),
|
||||||
|
_buildInfoRow('Pendidikan Terakhir',
|
||||||
|
penerima['pendidikanTerakhir'] ?? '-'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoRow(String label, String value) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 150,
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
value,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusSection(Map<String, dynamic> penerima) {
|
||||||
|
Color statusColor;
|
||||||
|
IconData statusIcon;
|
||||||
|
|
||||||
|
switch (penerima['status']) {
|
||||||
|
case 'Selesai':
|
||||||
|
statusColor = Colors.green;
|
||||||
|
statusIcon = Icons.check_circle;
|
||||||
|
break;
|
||||||
|
case 'Terjadwal':
|
||||||
|
statusColor = Colors.blue;
|
||||||
|
statusIcon = Icons.event;
|
||||||
|
break;
|
||||||
|
case 'Belum disalurkan':
|
||||||
|
statusColor = Colors.orange;
|
||||||
|
statusIcon = Icons.pending;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusColor = Colors.grey;
|
||||||
|
statusIcon = Icons.help;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Status Penyaluran',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Card(
|
||||||
|
elevation: 2,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: statusColor.withOpacity(0.1),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
statusIcon,
|
||||||
|
color: statusColor,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
penerima['status'] ?? 'Tidak diketahui',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: statusColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (penerima['status'] == 'Belum disalurkan')
|
||||||
|
const Text(
|
||||||
|
'Penerima ini belum dijadwalkan penyaluran bantuan',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (penerima['status'] == 'Terjadwal')
|
||||||
|
const Text(
|
||||||
|
'Penerima ini sudah dijadwalkan penyaluran bantuan',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (penerima['status'] == 'Selesai')
|
||||||
|
const Text(
|
||||||
|
'Penerima ini sudah menerima bantuan',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBottomButtons(Map<String, dynamic> penerima) {
|
||||||
|
// Jika status sudah selesai, tidak perlu menampilkan tombol
|
||||||
|
if (penerima['status'] == 'Selesai') {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi lihat riwayat penyaluran
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.history),
|
||||||
|
label: const Text('Lihat Riwayat Penyaluran'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: AppTheme.primaryColor,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika status belum disalurkan, tampilkan tombol jadwalkan
|
||||||
|
if (penerima['status'] == 'Belum disalurkan') {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi jadwalkan penyaluran
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.event),
|
||||||
|
label: const Text('Jadwalkan Penyaluran'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: AppTheme.primaryColor,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika status terjadwal, tampilkan tombol konfirmasi penyaluran
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi konfirmasi penyaluran
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.check_circle),
|
||||||
|
label: const Text('Konfirmasi Penyaluran'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
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/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/daftar_penerima_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/dashboard_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/dashboard_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/penyaluran_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/penyaluran_view.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/views/notifikasi_view.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/views/notifikasi_view.dart';
|
||||||
@ -334,6 +336,14 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
|
|||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.people_outline),
|
||||||
|
title: const Text('Daftar Penerima'),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context); // Tutup drawer terlebih dahulu
|
||||||
|
Get.toNamed('/daftar-penerima');
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Stack(
|
leading: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
@ -10,6 +10,10 @@ import 'package:penyaluran_app/app/modules/dashboard/bindings/dashboard_binding.
|
|||||||
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/detail_penerima_view.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/bindings/penerima_binding.dart';
|
||||||
|
|
||||||
part 'app_routes.dart';
|
part 'app_routes.dart';
|
||||||
|
|
||||||
@ -54,5 +58,15 @@ class AppPages {
|
|||||||
page: () => const PermintaanPenjadwalanView(),
|
page: () => const PermintaanPenjadwalanView(),
|
||||||
binding: PetugasDesaBinding(),
|
binding: PetugasDesaBinding(),
|
||||||
),
|
),
|
||||||
|
GetPage(
|
||||||
|
name: _Paths.daftarPenerima,
|
||||||
|
page: () => const DaftarPenerimaView(),
|
||||||
|
binding: PenerimaBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: _Paths.detailPenerima,
|
||||||
|
page: () => const DetailPenerimaView(),
|
||||||
|
binding: PenerimaBinding(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ abstract class Routes {
|
|||||||
static const donaturDashboard = _Paths.donaturDashboard;
|
static const donaturDashboard = _Paths.donaturDashboard;
|
||||||
static const splash = _Paths.splash;
|
static const splash = _Paths.splash;
|
||||||
static const permintaanPenjadwalan = _Paths.permintaanPenjadwalan;
|
static const permintaanPenjadwalan = _Paths.permintaanPenjadwalan;
|
||||||
|
static const daftarPenerima = _Paths.daftarPenerima;
|
||||||
|
static const detailPenerima = _Paths.detailPenerima;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _Paths {
|
abstract class _Paths {
|
||||||
@ -24,4 +26,6 @@ abstract class _Paths {
|
|||||||
static const donaturDashboard = '/donatur-dashboard';
|
static const donaturDashboard = '/donatur-dashboard';
|
||||||
static const splash = '/splash';
|
static const splash = '/splash';
|
||||||
static const permintaanPenjadwalan = '/permintaan-penjadwalan';
|
static const permintaanPenjadwalan = '/permintaan-penjadwalan';
|
||||||
|
static const daftarPenerima = '/daftar-penerima';
|
||||||
|
static const detailPenerima = '/daftar-penerima/detail';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user