Tambahkan rute baru untuk modul Warga, termasuk WargaDashboard, WargaPenyaluran, dan WargaPengaduan. Perbarui referensi import di app_pages.dart dan app_routes.dart untuk mencerminkan perubahan ini, meningkatkan struktur dan navigasi aplikasi.

This commit is contained in:
Khafidh Fuadi
2025-03-16 17:20:18 +07:00
parent dfc6080e77
commit a3798f0005
15 changed files with 1587 additions and 48 deletions

View File

@ -0,0 +1,187 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
class WargaPenyaluranView extends GetView<WargaDashboardController> {
const WargaPenyaluranView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(() {
if (controller.isLoading.value) {
return const Center(child: CircularProgressIndicator());
}
return RefreshIndicator(
onRefresh: () async {
controller.fetchData();
},
child: controller.penerimaPenyaluran.isEmpty
? _buildEmptyState()
: _buildPenyaluranList(),
);
});
}
Widget _buildEmptyState() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.volunteer_activism,
size: 80,
color: Colors.grey.shade400,
),
const SizedBox(height: 16),
Text(
'Belum Ada Penyaluran',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.grey.shade700,
),
),
const SizedBox(height: 8),
Text(
'Anda belum menerima penyaluran bantuan',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
],
),
);
}
Widget _buildPenyaluranList() {
final currencyFormat = NumberFormat.currency(
locale: 'id',
symbol: 'Rp ',
decimalDigits: 0,
);
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: controller.penerimaPenyaluran.length,
itemBuilder: (context, index) {
final item = controller.penerimaPenyaluran[index];
return Card(
margin: const EdgeInsets.only(bottom: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 2,
child: InkWell(
onTap: () {
// TODO: Navigasi ke detail penyaluran
},
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
item.keterangan ?? 'Bantuan',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.green),
),
child: const Text(
'Diterima',
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
),
],
),
const SizedBox(height: 16),
Row(
children: [
Icon(
Icons.calendar_today,
size: 16,
color: Colors.grey.shade600,
),
const SizedBox(width: 8),
Text(
item.tanggalPenerimaan != null
? DateFormat('dd MMMM yyyy', 'id_ID')
.format(item.tanggalPenerimaan!)
: '-',
style: TextStyle(
color: Colors.grey.shade600,
),
),
],
),
const SizedBox(height: 8),
Row(
children: [
Icon(
Icons.attach_money,
size: 16,
color: Colors.grey.shade600,
),
const SizedBox(width: 8),
Text(
item.jumlahBantuan != null
? currencyFormat.format(item.jumlahBantuan)
: '-',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
],
),
const SizedBox(height: 16),
const Divider(height: 1),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton.icon(
onPressed: () {
// TODO: Implementasi navigasi ke detail penyaluran
Get.toNamed('/detail-penyaluran',
arguments: {'id': item.id});
},
icon: const Icon(Icons.visibility),
label: const Text('Lihat Detail'),
),
],
),
],
),
),
),
);
},
);
}
}