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,487 @@
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';
import 'package:penyaluran_app/app/data/models/pengajuan_kelayakan_bantuan_model.dart';
class WargaDashboardView extends GetView<WargaDashboardController> {
const WargaDashboardView({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: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildWelcomeSection(),
const SizedBox(height: 24),
_buildPenyaluranSummary(),
const SizedBox(height: 24),
_buildPengajuanSection(),
const SizedBox(height: 24),
_buildPengaduanSummary(),
],
),
),
);
});
}
Widget _buildWelcomeSection() {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.blue.shade100,
child: const Icon(
Icons.person,
size: 40,
color: Colors.blue,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Selamat Datang,',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
const SizedBox(height: 4),
Text(
controller.nama,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
controller.desa ?? 'Warga Desa',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
],
),
),
],
),
),
);
}
Widget _buildPenyaluranSummary() {
final currencyFormat = NumberFormat.currency(
locale: 'id',
symbol: 'Rp ',
decimalDigits: 0,
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Penyaluran Bantuan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Total Bantuan Diterima',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
const SizedBox(height: 8),
Text(
'${controller.totalPenyaluranDiterima.value}',
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
],
),
const Icon(
Icons.volunteer_activism,
size: 40,
color: Colors.blue,
),
],
),
const Divider(height: 32),
if (controller.penerimaPenyaluran.isNotEmpty)
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.penerimaPenyaluran.length > 2
? 2
: controller.penerimaPenyaluran.length,
itemBuilder: (context, index) {
final item = controller.penerimaPenyaluran[index];
return ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
item.keterangan ?? 'Bantuan',
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
item.tanggalPenerimaan != null
? DateFormat('dd MMMM yyyy', 'id_ID')
.format(item.tanggalPenerimaan!)
: '-',
),
trailing: Text(
item.jumlahBantuan != null
? currencyFormat.format(item.jumlahBantuan)
: '-',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
);
},
)
else
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text('Belum ada penyaluran bantuan'),
),
),
if (controller.penerimaPenyaluran.length > 2)
TextButton(
onPressed: () => controller.changeTab(1),
child: const Text('Lihat Semua'),
),
],
),
),
),
],
);
}
Widget _buildPengajuanSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Pengajuan Kelayakan Bantuan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildStatusCounter(
'Menunggu',
controller.totalPengajuanMenunggu.value,
Colors.orange,
),
_buildStatusCounter(
'Terverifikasi',
controller.totalPengajuanTerverifikasi.value,
Colors.green,
),
_buildStatusCounter(
'Ditolak',
controller.totalPengajuanDitolak.value,
Colors.red,
),
],
),
const Divider(height: 32),
if (controller.pengajuanKelayakan.isNotEmpty)
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.pengajuanKelayakan.length > 3
? 3
: controller.pengajuanKelayakan.length,
itemBuilder: (context, index) {
final item = controller.pengajuanKelayakan[index];
return ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
'Pengajuan #${index + 1}',
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
item.createdAt != null
? DateFormat('dd MMMM yyyy', 'id_ID')
.format(item.createdAt!)
: '-',
),
trailing: _buildStatusBadge(item.status),
);
},
)
else
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text('Belum ada pengajuan kelayakan'),
),
),
if (controller.pengajuanKelayakan.length > 3)
TextButton(
onPressed: controller.goToPengajuanDetail,
child: const Text('Lihat Semua'),
),
],
),
),
),
],
);
}
Widget _buildStatusCounter(String label, int count, Color color) {
return Column(
children: [
Text(
'$count',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: color,
),
),
const SizedBox(height: 4),
Text(
label,
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
],
);
}
Widget _buildStatusBadge(StatusKelayakan? status) {
if (status == null) return const SizedBox();
Color color;
String text;
switch (status) {
case StatusKelayakan.MENUNGGU:
color = Colors.orange;
text = 'Menunggu';
break;
case StatusKelayakan.TERVERIFIKASI:
color = Colors.green;
text = 'Terverifikasi';
break;
case StatusKelayakan.DITOLAK:
color = Colors.red;
text = 'Ditolak';
break;
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: color),
),
child: Text(
text,
style: TextStyle(
color: color,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
);
}
Widget _buildPengaduanSummary() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Pengaduan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildStatusCounter(
'Total',
controller.totalPengaduan.value,
Colors.blue,
),
_buildStatusCounter(
'Proses',
controller.totalPengaduanProses.value,
Colors.orange,
),
_buildStatusCounter(
'Selesai',
controller.totalPengaduanSelesai.value,
Colors.green,
),
],
),
const Divider(height: 32),
if (controller.pengaduan.isNotEmpty)
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.pengaduan.length > 2
? 2
: controller.pengaduan.length,
itemBuilder: (context, index) {
final item = controller.pengaduan[index];
return ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
item.judul ?? 'Pengaduan #${index + 1}',
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
item.tanggalPengaduan != null
? DateFormat('dd MMMM yyyy', 'id_ID')
.format(item.tanggalPengaduan!)
: '-',
),
trailing: Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: item.status == 'PROSES'
? Colors.orange.withOpacity(0.1)
: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: item.status == 'PROSES'
? Colors.orange
: Colors.green,
),
),
child: Text(
item.status == 'PROSES' ? 'Proses' : 'Selesai',
style: TextStyle(
color: item.status == 'PROSES'
? Colors.orange
: Colors.green,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
),
);
},
)
else
const Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text('Belum ada pengaduan'),
),
),
if (controller.pengaduan.length > 2)
TextButton(
onPressed: () => controller.changeTab(2),
child: const Text('Lihat Semua'),
),
const SizedBox(height: 8),
ElevatedButton.icon(
onPressed: () {
// TODO: Implementasi navigasi ke halaman buat pengaduan
},
icon: const Icon(Icons.add),
label: const Text('Buat Pengaduan Baru'),
style: ElevatedButton.styleFrom(
minimumSize: const Size(double.infinity, 48),
),
),
],
),
),
),
],
);
}
}

View File

@ -0,0 +1,194 @@
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 WargaPengaduanView extends GetView<WargaDashboardController> {
const WargaPengaduanView({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.pengaduan.isEmpty
? _buildEmptyState()
: _buildPengaduanList(),
);
});
}
Widget _buildEmptyState() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.report_problem,
size: 80,
color: Colors.grey.shade400,
),
const SizedBox(height: 16),
Text(
'Belum Ada Pengaduan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.grey.shade700,
),
),
const SizedBox(height: 8),
Text(
'Anda belum membuat pengaduan',
style: TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
),
),
const SizedBox(height: 24),
ElevatedButton.icon(
onPressed: () {
// TODO: Implementasi navigasi ke halaman buat pengaduan
Get.toNamed('/buat-pengaduan');
},
icon: const Icon(Icons.add),
label: const Text('Buat Pengaduan Baru'),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
),
],
),
);
}
Widget _buildPengaduanList() {
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: controller.pengaduan.length,
itemBuilder: (context, index) {
final item = controller.pengaduan[index];
final isProses = item.status == 'PROSES';
return Card(
margin: const EdgeInsets.only(bottom: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 2,
child: InkWell(
onTap: () {
// TODO: Navigasi ke detail pengaduan
},
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.judul ?? 'Pengaduan #${index + 1}',
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: isProses
? Colors.orange.withOpacity(0.1)
: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: isProses ? Colors.orange : Colors.green,
),
),
child: Text(
isProses ? 'Proses' : 'Selesai',
style: TextStyle(
color: isProses ? Colors.orange : Colors.green,
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
),
],
),
const SizedBox(height: 12),
if (item.deskripsi != null && item.deskripsi!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Text(
item.deskripsi!,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey.shade700,
),
),
),
Row(
children: [
Icon(
Icons.calendar_today,
size: 16,
color: Colors.grey.shade600,
),
const SizedBox(width: 8),
Text(
item.tanggalPengaduan != null
? DateFormat('dd MMMM yyyy', 'id_ID')
.format(item.tanggalPengaduan!)
: '-',
style: TextStyle(
color: Colors.grey.shade600,
),
),
],
),
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 pengaduan
Get.toNamed('/detail-pengaduan',
arguments: {'id': item.id});
},
icon: const Icon(Icons.visibility),
label: const Text('Lihat Detail'),
),
],
),
],
),
),
),
);
},
);
}
}

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'),
),
],
),
],
),
),
),
);
},
);
}
}

View File

@ -0,0 +1,180 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
import 'package:penyaluran_app/app/modules/warga/views/warga_dashboard_view.dart';
import 'package:penyaluran_app/app/modules/warga/views/warga_penyaluran_view.dart';
import 'package:penyaluran_app/app/modules/warga/views/warga_pengaduan_view.dart';
import 'package:penyaluran_app/app/widgets/app_drawer.dart';
import 'package:penyaluran_app/app/widgets/app_bottom_navigation_bar.dart';
import 'package:penyaluran_app/app/theme/app_theme.dart';
class WargaView extends GetView<WargaDashboardController> {
const WargaView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Obx(() {
switch (controller.activeTabIndex.value) {
case 0:
return const Text('Dashboard Warga');
case 1:
return const Text('Penyaluran Bantuan');
case 2:
return const Text('Pengaduan');
default:
return const Text('Dashboard Warga');
}
}),
leading: IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
scaffoldKey.currentState?.openDrawer();
},
),
actions: [
// Tombol notifikasi
Stack(
alignment: Alignment.center,
children: [
IconButton(
icon: const Icon(Icons.notifications_outlined),
onPressed: () {
// Navigasi ke halaman notifikasi
Get.toNamed('/notifikasi');
},
),
Obx(() {
if (controller.jumlahNotifikasiBelumDibaca.value > 0) {
return Positioned(
top: 8,
right: 8,
child: Container(
padding: const EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
constraints: const BoxConstraints(
minWidth: 16,
minHeight: 16,
),
child: Text(
controller.jumlahNotifikasiBelumDibaca.value.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 10,
),
textAlign: TextAlign.center,
),
),
);
} else {
return const SizedBox.shrink();
}
}),
],
),
],
),
drawer: Obx(() => AppDrawer(
nama: controller.nama,
role: 'Warga',
desa: controller.desa,
notificationCount: controller.jumlahNotifikasiBelumDibaca.value,
onLogout: controller.logout,
menuItems: [
DrawerMenuItem(
icon: Icons.dashboard_outlined,
title: 'Dashboard',
isSelected: controller.activeTabIndex.value == 0,
onTap: () => controller.changeTab(0),
),
DrawerMenuItem(
icon: Icons.volunteer_activism_outlined,
title: 'Penyaluran',
isSelected: controller.activeTabIndex.value == 1,
onTap: () => controller.changeTab(1),
),
DrawerMenuItem(
icon: Icons.report_problem_outlined,
title: 'Pengaduan',
isSelected: controller.activeTabIndex.value == 2,
badgeCount: controller.totalPengaduanProses.value,
badgeColor: Colors.orange,
onTap: () => controller.changeTab(2),
),
DrawerMenuItem(
icon: Icons.assignment_outlined,
title: 'Pengajuan Kelayakan',
onTap: () {
// TODO: Navigasi ke halaman pengajuan kelayakan
Get.toNamed('/pengajuan-kelayakan');
},
badgeCount: controller.totalPengajuanMenunggu.value,
badgeColor: Colors.blue,
),
],
)),
body: Obx(() {
switch (controller.activeTabIndex.value) {
case 0:
return const WargaDashboardView();
case 1:
return const WargaPenyaluranView();
case 2:
return const WargaPengaduanView();
default:
return const WargaDashboardView();
}
}),
bottomNavigationBar: Obx(() => AppBottomNavigationBar(
currentIndex: controller.activeTabIndex.value,
onTap: controller.changeTab,
items: [
AppBottomNavigationBarItem(
icon: Icons.dashboard_outlined,
activeIcon: Icons.dashboard,
label: 'Beranda',
),
AppBottomNavigationBarItem(
icon: Icons.volunteer_activism_outlined,
activeIcon: Icons.volunteer_activism,
label: 'Penyaluran',
badgeCount: controller.totalPenyaluranDiterima.value > 0
? controller.totalPenyaluranDiterima.value
: null,
badgeColor: Colors.green,
),
AppBottomNavigationBarItem(
icon: Icons.report_problem_outlined,
activeIcon: Icons.report_problem,
label: 'Pengaduan',
badgeCount: controller.totalPengaduanProses.value > 0
? controller.totalPengaduanProses.value
: null,
badgeColor: Colors.orange,
),
],
)),
floatingActionButton: Obx(() {
// Tampilkan FAB hanya di halaman pengaduan
if (controller.activeTabIndex.value == 2) {
return FloatingActionButton(
onPressed: () {
// TODO: Implementasi navigasi ke halaman buat pengaduan
Get.toNamed('/buat-pengaduan');
},
backgroundColor: AppTheme.primaryColor,
child: const Icon(Icons.add),
);
}
return const SizedBox.shrink();
}),
);
}
}