Tambahkan dependensi baru timeline_tile versi 2.0.0 ke dalam pubspec.yaml dan pubspec.lock. Perbarui model PengaduanModel dan TindakanPengaduanModel untuk mendukung struktur data yang lebih kompleks, termasuk penambahan properti baru. Modifikasi PengaduanController untuk menggunakan metode baru dalam mengambil data pengaduan dengan detail penerima penyaluran. Perbarui tampilan di PengaduanView untuk meningkatkan pengalaman pengguna dengan menampilkan informasi penyaluran bantuan yang lebih lengkap.
This commit is contained in:
@ -273,11 +273,15 @@ class WargaDashboardController extends GetxController {
|
||||
// Fungsi untuk mengambil data pengaduan
|
||||
Future<void> fetchPengaduan() async {
|
||||
try {
|
||||
final response = await _supabaseService.client
|
||||
.from('pengaduan')
|
||||
.select('*')
|
||||
.eq('pelapor', user!.id)
|
||||
.order('created_at', ascending: false);
|
||||
final wargaData = await _supabaseService.getWargaByUserId();
|
||||
if (wargaData == null) {
|
||||
print('Data warga tidak ditemukan');
|
||||
return;
|
||||
}
|
||||
|
||||
final String wargaId = wargaData['id'];
|
||||
final response = await _supabaseService
|
||||
.getPengaduanWargaWithPenerimaPenyaluran(wargaId);
|
||||
|
||||
if (response != null) {
|
||||
final List<PengaduanModel> pengaduanList = [];
|
||||
@ -289,7 +293,7 @@ class WargaDashboardController extends GetxController {
|
||||
// Hitung jumlah berdasarkan status
|
||||
totalPengaduan.value = pengaduanList.length;
|
||||
totalPengaduanProses.value = pengaduanList
|
||||
.where((p) => p.status == 'PROSES' || p.status == 'DIPROSES')
|
||||
.where((p) => p.status == 'MENUNGGU' || p.status == 'TINDAKAN')
|
||||
.length;
|
||||
totalPengaduanSelesai.value =
|
||||
pengaduanList.where((p) => p.status == 'SELESAI').length;
|
||||
@ -342,4 +346,39 @@ class WargaDashboardController extends GetxController {
|
||||
void logout() {
|
||||
_authController.logout();
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getDetailPengaduan(String pengaduanId) async {
|
||||
try {
|
||||
// Ambil data pengaduan
|
||||
final pengaduanData =
|
||||
await _supabaseService.client.from('pengaduan').select('''
|
||||
*,
|
||||
penerima_penyaluran:penerima_penyaluran_id(
|
||||
*,
|
||||
penyaluran_bantuan:penyaluran_bantuan_id(*),
|
||||
stok_bantuan:stok_bantuan_id(*),
|
||||
warga:warga_id(*)
|
||||
),
|
||||
warga:warga_id(*)
|
||||
''').eq('id', pengaduanId).single();
|
||||
|
||||
// Ambil data tindakan pengaduan
|
||||
final tindakanData =
|
||||
await _supabaseService.getTindakanPengaduan(pengaduanId);
|
||||
|
||||
// Gabungkan data
|
||||
final result = {
|
||||
'pengaduan': pengaduanData,
|
||||
'tindakan': tindakanData ?? [],
|
||||
};
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
print('Error getting detail pengaduan: $e');
|
||||
return {
|
||||
'pengaduan': null,
|
||||
'tindakan': [],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
449
lib/app/modules/warga/views/detail_pengaduan_view.dart
Normal file
449
lib/app/modules/warga/views/detail_pengaduan_view.dart
Normal file
@ -0,0 +1,449 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:penyaluran_app/app/data/models/pengaduan_model.dart';
|
||||
import 'package:penyaluran_app/app/data/models/tindakan_pengaduan_model.dart';
|
||||
import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
|
||||
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||
import 'package:timeline_tile/timeline_tile.dart';
|
||||
|
||||
class WargaDetailPengaduanView extends GetView<WargaDashboardController> {
|
||||
const WargaDetailPengaduanView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Map<String, dynamic> args = Get.arguments ?? {};
|
||||
final String pengaduanId = args['id'] ?? '';
|
||||
|
||||
if (pengaduanId.isEmpty) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Detail Pengaduan'),
|
||||
),
|
||||
body: const Center(
|
||||
child: Text('ID Pengaduan tidak valid'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Detail Pengaduan'),
|
||||
elevation: 0,
|
||||
),
|
||||
body: FutureBuilder<Map<String, dynamic>>(
|
||||
future: controller.getDetailPengaduan(pengaduanId),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text('Error: ${snapshot.error}'),
|
||||
);
|
||||
}
|
||||
|
||||
final data = snapshot.data;
|
||||
if (data == null || data['pengaduan'] == null) {
|
||||
return const Center(
|
||||
child: Text('Data pengaduan tidak ditemukan'),
|
||||
);
|
||||
}
|
||||
|
||||
final pengaduan = PengaduanModel.fromJson(data['pengaduan']);
|
||||
final List<TindakanPengaduanModel> tindakanList =
|
||||
(data['tindakan'] as List)
|
||||
.map((item) => TindakanPengaduanModel.fromJson(item))
|
||||
.toList();
|
||||
|
||||
return _buildDetailContent(context, pengaduan, tindakanList);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDetailContent(
|
||||
BuildContext context,
|
||||
PengaduanModel pengaduan,
|
||||
List<TindakanPengaduanModel> tindakanList,
|
||||
) {
|
||||
// Tentukan status dan warna
|
||||
Color statusColor;
|
||||
String statusText;
|
||||
|
||||
switch (pengaduan.status?.toUpperCase()) {
|
||||
case 'MENUNGGU':
|
||||
statusColor = Colors.orange;
|
||||
statusText = 'Menunggu';
|
||||
break;
|
||||
case 'TINDAKAN':
|
||||
statusColor = Colors.blue;
|
||||
statusText = 'Tindakan';
|
||||
break;
|
||||
case 'SELESAI':
|
||||
statusColor = Colors.green;
|
||||
statusText = 'Selesai';
|
||||
break;
|
||||
default:
|
||||
statusColor = Colors.grey;
|
||||
statusText = pengaduan.status ?? 'Tidak Diketahui';
|
||||
}
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Header dengan status
|
||||
_buildHeaderWithStatus(context, pengaduan, statusColor, statusText),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Informasi penyaluran yang diadukan
|
||||
if (pengaduan.penerimaPenyaluran != null)
|
||||
_buildPenyaluranInfo(context, pengaduan),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Timeline tindakan
|
||||
_buildTindakanTimeline(context, tindakanList),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeaderWithStatus(
|
||||
BuildContext context,
|
||||
PengaduanModel pengaduan,
|
||||
Color statusColor,
|
||||
String statusText,
|
||||
) {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
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(
|
||||
pengaduan.judul ?? 'Pengaduan',
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: statusColor,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
statusText,
|
||||
style: TextStyle(
|
||||
color: statusColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
pengaduan.deskripsi ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
pengaduan.tanggalPengaduan != null
|
||||
? DateFormat('dd MMMM yyyy', 'id_ID')
|
||||
.format(pengaduan.tanggalPengaduan!)
|
||||
: '-',
|
||||
style: TextStyle(
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPenyaluranInfo(BuildContext context, PengaduanModel pengaduan) {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Informasi Penyaluran',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildInfoRow('Nama Penyaluran', pengaduan.namaPenyaluran),
|
||||
_buildInfoRow('Jenis Bantuan', pengaduan.jenisBantuan),
|
||||
_buildInfoRow('Jumlah Bantuan', pengaduan.jumlahBantuan),
|
||||
_buildInfoRow('Deskripsi', pengaduan.deskripsiPenyaluran),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTindakanTimeline(
|
||||
BuildContext context,
|
||||
List<TindakanPengaduanModel> tindakanList,
|
||||
) {
|
||||
if (tindakanList.isEmpty) {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pengaduan Anda sedang menunggu tindakan dari petugas',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Riwayat Tindakan',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: tindakanList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final tindakan = tindakanList[index];
|
||||
final bool isFirst = index == 0;
|
||||
final bool isLast = index == tindakanList.length - 1;
|
||||
|
||||
return _buildTimelineTile(
|
||||
context,
|
||||
tindakan,
|
||||
isFirst,
|
||||
isLast,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTimelineTile(
|
||||
BuildContext context,
|
||||
TindakanPengaduanModel tindakan,
|
||||
bool isFirst,
|
||||
bool isLast,
|
||||
) {
|
||||
Color dotColor;
|
||||
switch (tindakan.statusTindakan) {
|
||||
case 'SELESAI':
|
||||
dotColor = Colors.green;
|
||||
break;
|
||||
case 'PROSES':
|
||||
dotColor = Colors.blue;
|
||||
break;
|
||||
default:
|
||||
dotColor = Colors.grey;
|
||||
}
|
||||
|
||||
return TimelineTile(
|
||||
alignment: TimelineAlign.start,
|
||||
isFirst: isFirst,
|
||||
isLast: isLast,
|
||||
indicatorStyle: IndicatorStyle(
|
||||
width: 20,
|
||||
color: dotColor,
|
||||
iconStyle: IconStyle(
|
||||
color: Colors.white,
|
||||
iconData:
|
||||
tindakan.statusTindakan == 'SELESAI' ? Icons.check : Icons.sync,
|
||||
),
|
||||
),
|
||||
endChild: Container(
|
||||
margin: const EdgeInsets.only(left: 16, bottom: 24),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 2,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
tindakan.kategoriTindakanText,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: dotColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
tindakan.statusTindakanText,
|
||||
style: TextStyle(
|
||||
color: dotColor,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
tindakan.tindakan ?? '',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
if (tindakan.hasilTindakan != null &&
|
||||
tindakan.hasilTindakan!.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Hasil: ${tindakan.hasilTindakan}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Oleh: ${tindakan.namaPetugas}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
tindakan.tanggalTindakan != null
|
||||
? DateFormat('dd MMM yyyy', 'id_ID')
|
||||
.format(tindakan.tanggalTindakan!)
|
||||
: '-',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 120,
|
||||
child: Text(
|
||||
'$label:',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ 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/routes/app_pages.dart';
|
||||
import 'package:penyaluran_app/app/widgets/bantuan_card.dart';
|
||||
import 'package:penyaluran_app/app/widgets/section_header.dart';
|
||||
|
||||
@ -290,10 +291,9 @@ class WargaDashboardView extends GetView<WargaDashboardController> {
|
||||
title: 'Bantuan Terbaru',
|
||||
viewAllText: 'Lihat Semua',
|
||||
onViewAll: () {
|
||||
Get.toNamed('/warga-penerimaan');
|
||||
Get.toNamed(Routes.wargaPenerimaan);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
|
@ -2,6 +2,7 @@ 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/utils/date_time_helper.dart';
|
||||
|
||||
class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
const WargaPengaduanView({Key? key}) : super(key: key);
|
||||
@ -83,11 +84,13 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
String statusText;
|
||||
|
||||
switch (item.status?.toUpperCase()) {
|
||||
case 'PROSES':
|
||||
case 'DIPROSES':
|
||||
case 'TINDAKAN':
|
||||
case 'MENUNGGU':
|
||||
statusColor = Colors.orange;
|
||||
statusText = 'Proses';
|
||||
statusText = 'Menunggu';
|
||||
break;
|
||||
case 'TINDAKAN':
|
||||
statusColor = Colors.blue;
|
||||
statusText = 'Tindakan';
|
||||
break;
|
||||
case 'SELESAI':
|
||||
statusColor = Colors.green;
|
||||
@ -102,8 +105,6 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
statusText = item.status ?? 'Tidak Diketahui';
|
||||
}
|
||||
|
||||
final isProses = statusText == 'Proses';
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
shape: RoundedRectangleBorder(
|
||||
@ -112,7 +113,9 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
elevation: 2,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// TODO: Navigasi ke detail pengaduan
|
||||
// Navigasi ke detail pengaduan
|
||||
Get.toNamed('/warga/detail-pengaduan',
|
||||
arguments: {'id': item.id});
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
@ -158,6 +161,52 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Informasi penyaluran bantuan
|
||||
if (item.penerimaPenyaluran != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.shade50,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Penyaluran: ${item.namaPenyaluran}',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Jenis: ${item.jenisBantuan}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Jumlah: ${item.jumlahBantuan}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
if (item.deskripsi != null && item.deskripsi!.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
@ -180,8 +229,8 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
item.tanggalPengaduan != null
|
||||
? DateFormat('dd MMMM yyyy', 'id_ID')
|
||||
.format(item.tanggalPengaduan!)
|
||||
? DateTimeHelper.formatDateTime(
|
||||
item.tanggalPengaduan!)
|
||||
: '-',
|
||||
style: TextStyle(
|
||||
color: Colors.grey.shade600,
|
||||
@ -197,8 +246,8 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: () {
|
||||
// TODO: Implementasi navigasi ke detail pengaduan
|
||||
Get.toNamed('/detail-pengaduan',
|
||||
// Navigasi ke detail pengaduan
|
||||
Get.toNamed('/warga/detail-pengaduan',
|
||||
arguments: {'id': item.id});
|
||||
},
|
||||
icon: const Icon(Icons.visibility),
|
||||
|
Reference in New Issue
Block a user