From 295b76e40f0a9444f7f7b488955b8529688d1a29 Mon Sep 17 00:00:00 2001 From: Khafidh Fuadi Date: Sat, 15 Mar 2025 15:13:41 +0700 Subject: [PATCH] Perbarui JadwalSectionWidget dan KonfirmasiPenerimaView untuk menyederhanakan pengiriman data. Hapus konversi model ke Map dan hanya kirim ID penyaluran. Modifikasi tampilan KonfirmasiPenerimaView untuk menggunakan data dari arguments dan memperbarui logika tampilan penerima. Hapus tampilan PelaksanaanPenyaluranView yang tidak digunakan dan perbarui rute aplikasi untuk mencerminkan perubahan ini. --- .../pelaksanaan_penyaluran_binding.dart | 11 + .../components/jadwal_section_widget.dart | 41 +- .../controllers/petugas_desa_controller.dart | 2 - .../views/konfirmasi_penerima_view.dart | 173 ++-- .../views/pelaksanaan_penyaluran_view.dart | 878 ------------------ .../petugas_desa/views/petugas_desa_view.dart | 4 - .../views/tambah_penyaluran_view.dart | 128 ++- lib/app/routes/app_pages.dart | 6 - lib/app/routes/app_routes.dart | 6 + lib/app/services/supabase_service.dart | 1 - 10 files changed, 178 insertions(+), 1072 deletions(-) create mode 100644 lib/app/modules/petugas_desa/bindings/pelaksanaan_penyaluran_binding.dart delete mode 100644 lib/app/modules/petugas_desa/views/pelaksanaan_penyaluran_view.dart diff --git a/lib/app/modules/petugas_desa/bindings/pelaksanaan_penyaluran_binding.dart b/lib/app/modules/petugas_desa/bindings/pelaksanaan_penyaluran_binding.dart new file mode 100644 index 0000000..90cddb1 --- /dev/null +++ b/lib/app/modules/petugas_desa/bindings/pelaksanaan_penyaluran_binding.dart @@ -0,0 +1,11 @@ +import 'package:get/get.dart'; +import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart'; + +class PelaksanaanPenyaluranBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut( + () => PelaksanaanPenyaluranController(), + ); + } +} diff --git a/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart b/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart index 4e95f27..8c8a20b 100644 --- a/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart +++ b/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:intl/intl.dart'; import 'package:penyaluran_app/app/data/models/penyaluran_bantuan_model.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart'; import 'package:penyaluran_app/app/routes/app_pages.dart'; @@ -204,24 +203,8 @@ class JadwalSectionWidget extends StatelessWidget { child: InkWell( borderRadius: BorderRadius.circular(12), onTap: () { - // Konversi PenyaluranBantuanModel ke Map - final jadwalMap = { - 'id': jadwal.id, - 'nama': jadwal.nama, - 'deskripsi': jadwal.deskripsi, - 'lokasi': jadwal.nama, // Gunakan nama sebagai lokasi - 'kategori_bantuan': jadwal.kategoriBantuanId, - 'tanggal': jadwal.tanggalPenyaluran != null - ? DateTimeHelper.formatDate(jadwal.tanggalPenyaluran) - : '-', - 'waktu': jadwal.tanggalPenyaluran != null - ? DateTimeHelper.formatTime(jadwal.tanggalPenyaluran) - : '-', - 'jumlah_penerima': jadwal.jumlahPenerima, - 'status': jadwal.status, - }; - - Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwalMap); + // Hanya kirim ID penyaluran + Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwal.id); }, child: Padding( padding: const EdgeInsets.all(16), @@ -336,25 +319,9 @@ class JadwalSectionWidget extends StatelessWidget { alignment: Alignment.centerRight, child: TextButton.icon( onPressed: () { - // Konversi PenyaluranBantuanModel ke Map - final jadwalMap = { - 'id': jadwal.id, - 'nama': jadwal.nama, - 'deskripsi': jadwal.deskripsi, - 'lokasi': jadwal.nama, // Gunakan nama sebagai lokasi - 'kategori_bantuan': jadwal.kategoriBantuanId, - 'tanggal': jadwal.tanggalPenyaluran != null - ? DateTimeHelper.formatDate(jadwal.tanggalPenyaluran) - : '-', - 'waktu': jadwal.tanggalPenyaluran != null - ? DateTimeHelper.formatTime(jadwal.tanggalPenyaluran) - : '-', - 'jumlah_penerima': jadwal.jumlahPenerima, - 'status': jadwal.status, - }; - + // Hanya kirim ID penyaluran Get.toNamed(Routes.pelaksanaanPenyaluran, - arguments: jadwalMap); + arguments: jadwal.id); }, icon: const Icon(Icons.info_outline, size: 16), label: const Text('Lihat Detail'), diff --git a/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart b/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart index 5728121..aad316c 100644 --- a/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart @@ -219,8 +219,6 @@ class PetugasDesaController extends GetxController { // Update counter _counterService.updatePengaduanCounter(diproses); - - print('Jumlah pengaduan diproses: $diproses'); } else { _counterService.updatePengaduanCounter(0); } diff --git a/lib/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart b/lib/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart index d614e24..9dc35c3 100644 --- a/lib/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart +++ b/lib/app/modules/petugas_desa/views/konfirmasi_penerima_view.dart @@ -1,14 +1,26 @@ 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/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart'; import 'package:penyaluran_app/app/theme/app_theme.dart'; -class KonfirmasiPenerimaView extends GetView { +class KonfirmasiPenerimaView extends GetView { const KonfirmasiPenerimaView({super.key}); @override Widget build(BuildContext context) { - final String id = Get.arguments as String; + // Ambil data dari arguments + final Map args = Get.arguments ?? {}; + + // Pastikan semua parameter yang diperlukan tersedia + final penerimaId = args['penerima_id'] ?? 0; + final String penyaluranId = args['penyaluran_id']?.toString() ?? ''; + final Map warga = + args['warga'] as Map? ?? {}; + final Map jadwal = + args['jadwal'] as Map? ?? {}; + final String statusPenerimaan = + args['status_penerimaan']?.toString() ?? 'BELUMMENERIMA'; + final dynamic jumlahBantuan = args['jumlah_bantuan'] ?? 1; return Obx(() { if (controller.isLoading.value) { @@ -22,19 +34,6 @@ class KonfirmasiPenerimaView extends GetView { ); } - final penerima = controller.getPenerimaById(id); - - if (penerima == null) { - return Scaffold( - appBar: AppBar( - title: const Text('Konfirmasi Penerima'), - ), - body: const Center( - child: Text('Data penerima tidak ditemukan'), - ), - ); - } - return Scaffold( appBar: AppBar( title: const Text('Konfirmasi Penerima'), @@ -47,27 +46,28 @@ class KonfirmasiPenerimaView extends GetView { child: Column( children: [ // Header dengan foto dan nama - _buildHeader(penerima), + _buildHeader(warga), // Detail informasi penerima - _buildDetailInfo(penerima), + _buildDetailInfo(warga), // Detail jadwal dan bantuan - _buildDetailJadwalBantuan(penerima), + _buildDetailJadwalBantuan(jadwal, jumlahBantuan), // Form konfirmasi - _buildKonfirmasiForm(context, penerima), + _buildKonfirmasiForm(context, penerimaId, penyaluranId), const SizedBox(height: 20), ], ), ), - bottomNavigationBar: _buildBottomButtons(penerima), + bottomNavigationBar: + _buildBottomButtons(penerimaId, penyaluranId, statusPenerimaan), ); }); } - Widget _buildHeader(Map penerima) { + Widget _buildHeader(Map warga) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), @@ -80,11 +80,11 @@ class KonfirmasiPenerimaView extends GetView { CircleAvatar( radius: 40, backgroundColor: Colors.white, - child: penerima['foto'] != null + child: warga['foto_url'] != null ? ClipRRect( borderRadius: BorderRadius.circular(40), - child: Image.asset( - penerima['foto'], + child: Image.network( + warga['foto_url'], width: 80, height: 80, fit: BoxFit.cover, @@ -106,7 +106,7 @@ class KonfirmasiPenerimaView extends GetView { const SizedBox(height: 12), // Nama penerima Text( - penerima['nama'] ?? 'Nama tidak tersedia', + warga['nama'] ?? 'Nama tidak tersedia', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, @@ -116,7 +116,7 @@ class KonfirmasiPenerimaView extends GetView { const SizedBox(height: 4), // NIK Text( - penerima['nik'] ?? 'NIK tidak tersedia', + warga['nik'] ?? 'NIK tidak tersedia', style: const TextStyle( fontSize: 14, color: Colors.white, @@ -127,24 +127,23 @@ class KonfirmasiPenerimaView extends GetView { Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), decoration: BoxDecoration( - color: penerima['status'] == 'Terjadwal' - ? AppTheme.scheduledColor - : AppTheme.completedColor, + color: controller.getStatusColor( + warga['status_penerimaan'] ?? 'BELUMMENERIMA'), borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( - penerima['status'] == 'Terjadwal' - ? Icons.event_available - : Icons.check_circle, + controller.getStatusIcon( + warga['status_penerimaan'] ?? 'BELUMMENERIMA'), color: Colors.white, size: 16, ), const SizedBox(width: 4), Text( - penerima['status'] ?? 'Status tidak tersedia', + controller.getStatusText( + warga['status_penerimaan'] ?? 'BELUMMENERIMA'), style: const TextStyle( color: Colors.white, fontSize: 12, @@ -159,7 +158,7 @@ class KonfirmasiPenerimaView extends GetView { ); } - Widget _buildDetailInfo(Map penerima) { + Widget _buildDetailInfo(Map warga) { return Container( padding: const EdgeInsets.all(16), child: Column( @@ -182,21 +181,19 @@ class KonfirmasiPenerimaView extends GetView { padding: const EdgeInsets.all(16), child: Column( children: [ - _buildDetailRow('NIK', penerima['nik'] ?? '-'), - _buildDetailRow('No KK', penerima['noKK'] ?? '-'), + _buildDetailRow('NIK', warga['nik'] ?? '-'), + _buildDetailRow('No KK', warga['no_kk'] ?? '-'), + _buildDetailRow('No Handphone', warga['no_hp'] ?? '-'), + _buildDetailRow('Email', warga['email'] ?? '-'), _buildDetailRow( - 'No Handphone', penerima['noHandphone'] ?? '-'), - _buildDetailRow('Email', penerima['email'] ?? '-'), - _buildDetailRow( - 'Jenis Kelamin', penerima['jenisKelamin'] ?? '-'), - _buildDetailRow('Agama', penerima['agama'] ?? '-'), + 'Jenis Kelamin', warga['jenis_kelamin'] ?? '-'), + _buildDetailRow('Agama', warga['agama'] ?? '-'), _buildDetailRow('Tempat, Tanggal Lahir', - penerima['tempatTanggalLahir'] ?? '-'), + '${warga['tempat_lahir'] ?? '-'}, ${warga['tanggal_lahir'] ?? '-'}'), + _buildDetailRow('Alamat Lengkap', warga['alamat'] ?? '-'), + _buildDetailRow('Pekerjaan', warga['pekerjaan'] ?? '-'), _buildDetailRow( - 'Alamat Lengkap', penerima['alamatLengkap'] ?? '-'), - _buildDetailRow('Pekerjaan', penerima['pekerjaan'] ?? '-'), - _buildDetailRow('Pendidikan Terakhir', - penerima['pendidikanTerakhir'] ?? '-'), + 'Pendidikan Terakhir', warga['pendidikan'] ?? '-'), ], ), ), @@ -206,17 +203,8 @@ class KonfirmasiPenerimaView extends GetView { ); } - Widget _buildDetailJadwalBantuan(Map penerima) { - // Simulasi data jadwal dan bantuan - final jadwalBantuan = { - 'tanggal': '15 Agustus 2023', - 'waktu': '09:00 - 12:00 WIB', - 'lokasi': 'Balai Desa Gunung Putri, Jl. Raya Gunung Putri No. 10', - 'jenisBantuan': 'Bantuan Sosial Tunai (BST)', - 'nilaiNominal': 'Rp 600.000', - 'keterangan': 'Bantuan diberikan dalam bentuk tunai' - }; - + Widget _buildDetailJadwalBantuan( + Map jadwal, dynamic jumlahBantuan) { return Container( padding: const EdgeInsets.all(16), child: Column( @@ -240,15 +228,13 @@ class KonfirmasiPenerimaView extends GetView { child: Column( children: [ _buildDetailRow( - 'Tanggal Penyaluran', jadwalBantuan['tanggal'] ?? '-'), - _buildDetailRow('Waktu', jadwalBantuan['waktu'] ?? '-'), - _buildDetailRow('Lokasi', jadwalBantuan['lokasi'] ?? '-'), + 'Tanggal Penyaluran', jadwal['tanggal'] ?? '-'), + _buildDetailRow('Waktu', jadwal['waktu'] ?? '-'), + _buildDetailRow('Lokasi', jadwal['lokasi'] ?? '-'), _buildDetailRow( - 'Jenis Bantuan', jadwalBantuan['jenisBantuan'] ?? '-'), - _buildDetailRow( - 'Nilai Nominal', jadwalBantuan['nilaiNominal'] ?? '-'), - _buildDetailRow( - 'Keterangan', jadwalBantuan['keterangan'] ?? '-'), + 'Jenis Bantuan', jadwal['jenis_bantuan'] ?? '-'), + _buildDetailRow('Jumlah Bantuan', '$jumlahBantuan item'), + _buildDetailRow('Keterangan', jadwal['keterangan'] ?? '-'), ], ), ), @@ -289,7 +275,7 @@ class KonfirmasiPenerimaView extends GetView { } Widget _buildKonfirmasiForm( - BuildContext context, Map penerima) { + BuildContext context, int penerimaId, String penyaluranId) { return Container( padding: const EdgeInsets.all(16), child: Column( @@ -470,11 +456,23 @@ class KonfirmasiPenerimaView extends GetView { children: [ ClipRRect( borderRadius: BorderRadius.circular(8), - child: Image.asset( + child: Image.network( controller.fotoBuktiPath.value, height: 200, width: double.infinity, fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Container( + height: 200, + width: double.infinity, + color: Colors.grey.shade200, + child: const Icon( + Icons.broken_image, + size: 40, + color: Colors.grey, + ), + ); + }, ), ), Positioned( @@ -545,11 +543,23 @@ class KonfirmasiPenerimaView extends GetView { children: [ ClipRRect( borderRadius: BorderRadius.circular(8), - child: Image.asset( + child: Image.network( controller.tandaTanganPath.value, height: 150, width: double.infinity, fit: BoxFit.contain, + errorBuilder: (context, error, stackTrace) { + return Container( + height: 150, + width: double.infinity, + color: Colors.grey.shade200, + child: const Icon( + Icons.broken_image, + size: 40, + color: Colors.grey, + ), + ); + }, ), ), Positioned( @@ -606,7 +616,10 @@ class KonfirmasiPenerimaView extends GetView { ); } - Widget _buildBottomButtons(Map penerima) { + Widget _buildBottomButtons( + int penerimaId, String penyaluranId, String statusPenerimaan) { + final bool sudahDiterima = statusPenerimaan == 'SUDAHMENERIMA'; + return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( @@ -631,18 +644,22 @@ class KonfirmasiPenerimaView extends GetView { const SizedBox(width: 16), Expanded( child: Obx(() => ElevatedButton( - onPressed: controller.isKonfirmasiChecked.value && - controller.isIdentitasChecked.value && - controller.isDataValidChecked.value && - controller.fotoBuktiPath.value.isNotEmpty && - controller.tandaTanganPath.value.isNotEmpty - ? () => controller.konfirmasiPenyaluran(penerima['id']) - : null, + onPressed: sudahDiterima + ? null + : (controller.isKonfirmasiChecked.value && + controller.isIdentitasChecked.value && + controller.isDataValidChecked.value && + controller.fotoBuktiPath.value.isNotEmpty && + controller.tandaTanganPath.value.isNotEmpty + ? () => controller.konfirmasiPenyaluran( + penerimaId, penyaluranId) + : null), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.primaryColor, disabledBackgroundColor: Colors.grey.shade300, ), - child: const Text('Konfirmasi'), + child: + Text(sudahDiterima ? 'Sudah Dikonfirmasi' : 'Konfirmasi'), )), ), ], diff --git a/lib/app/modules/petugas_desa/views/pelaksanaan_penyaluran_view.dart b/lib/app/modules/petugas_desa/views/pelaksanaan_penyaluran_view.dart deleted file mode 100644 index 453c25c..0000000 --- a/lib/app/modules/petugas_desa/views/pelaksanaan_penyaluran_view.dart +++ /dev/null @@ -1,878 +0,0 @@ -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 { - const PelaksanaanPenyaluranView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - // Ambil data jadwal dari parameter - final jadwal = Get.arguments as Map; - - // Debug: Tampilkan data jadwal yang diterima - print('DEBUG: Jadwal yang diterima: $jadwal'); - print('DEBUG: ID Jadwal: ${jadwal['id']}'); - - // Debug: Periksa koneksi ke Supabase menggunakan instance dari controller - try { - controller.supabaseService.client - .from('penyaluran_bantuan') - .select('id') - .limit(1) - .then((_) { - print('DEBUG: Koneksi ke Supabase berhasil'); - }).catchError((error) { - print('DEBUG: Koneksi ke Supabase gagal: $error'); - }); - } catch (e) { - print('DEBUG: Error saat memeriksa koneksi Supabase: $e'); - } - - // Debug: Periksa struktur data jadwal - controller.debugJadwalData(jadwal); - - // Muat data penerima saat halaman dimuat - WidgetsBinding.instance.addPostFrameCallback((_) { - controller.reloadPenerimaPenyaluran(); - }); - - return Scaffold( - appBar: AppBar( - title: const Text('Pelaksanaan Penyaluran'), - // actions: [ - // // Tombol debug untuk melihat SQL query - // IconButton( - // icon: const Icon(Icons.code), - // onPressed: () { - // final penyaluranId = Get.parameters['id'] ?? jadwal['id']; - // _showSqlDebugDialog(context, penyaluranId); - // }, - // tooltip: 'Lihat SQL Query', - // ), - // ], - ), - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Informasi jadwal - Container( - padding: const EdgeInsets.all(16), - margin: const EdgeInsets.all(16), - 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: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildHeaderInfo(context, jadwal), - ], - ), - ), - - // Daftar penerima bantuan - _buildDaftarPenerima(context, jadwal), - ], - ), - ), - bottomNavigationBar: _buildBottomButtons(context, jadwal), - ); - } - - Widget _buildHeaderInfo(BuildContext context, Map jadwal) { - final textTheme = Theme.of(context).textTheme; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - jadwal['lokasi'] ?? 'Lokasi Penyaluran', - style: textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 16), - _buildInfoItem( - context, - icon: Icons.category, - label: 'Jenis Bantuan', - value: jadwal['jenis_bantuan'] ?? 'Tidak tersedia', - ), - _buildInfoItem( - context, - icon: Icons.calendar_today, - label: 'Tanggal', - value: jadwal['tanggal'] ?? 'Tidak tersedia', - ), - _buildInfoItem( - context, - icon: Icons.access_time, - label: 'Waktu', - value: jadwal['waktu'] ?? 'Tidak tersedia', - ), - _buildInfoItem( - context, - icon: Icons.people, - label: 'Jumlah Penerima', - value: '${controller.jumlahPenerima} orang', - ), - ], - ); - } - - Widget _buildInfoItem( - BuildContext context, { - required IconData icon, - required String label, - required String value, - bool isStatus = false, - }) { - final bool isActive = isStatus && value.toUpperCase() == 'AKTIF'; - - return Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: Row( - children: [ - Icon( - icon, - size: 18, - color: Colors.grey[600], - ), - const SizedBox(width: 8), - Text( - '$label: ', - style: const TextStyle( - fontWeight: FontWeight.w500, - ), - ), - if (isStatus) - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - decoration: BoxDecoration( - color: isActive ? Colors.green[50] : Colors.orange[50], - borderRadius: BorderRadius.circular(12), - ), - child: Text( - value, - style: TextStyle( - color: isActive ? Colors.green : Colors.orange, - fontWeight: FontWeight.w500, - ), - ), - ) - else - Expanded( - child: Text( - value, - style: const TextStyle( - fontWeight: FontWeight.w500, - ), - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - ); - } - - Widget _buildDaftarPenerima( - BuildContext context, Map jadwal) { - // Debug: Periksa validitas ID penyaluran - final penyaluranId = jadwal['id']; - if (penyaluranId == null || penyaluranId.toString().isEmpty) { - print('DEBUG: PERINGATAN! ID penyaluran kosong atau null: $penyaluranId'); - - // Tampilkan pesan error jika ID tidak valid - return Padding( - padding: const EdgeInsets.all(16), - child: Center( - child: Column( - children: [ - const Icon(Icons.error_outline, color: Colors.red, size: 48), - const SizedBox(height: 16), - Text( - 'ID penyaluran tidak valid: $penyaluranId', - style: TextStyle(color: Colors.red), - textAlign: TextAlign.center, - ), - ], - ), - ), - ); - } - - 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, - ), - ), - Obx(() => Text( - '${controller.jumlahPenerima.value} orang', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Colors.grey.shade600, - ), - )), - ], - ), - const SizedBox(height: 16), - - // Search bar - TextField( - controller: controller.searchPenerimaController, - onChanged: (value) => controller.filterPenerima(value), - 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', controller.filterStatus.value == 'SEMUA'), - const SizedBox(width: 8), - _buildFilterChip(context, 'Sudah Diterima', - controller.filterStatus.value == 'SUDAHMENERIMA'), - const SizedBox(width: 8), - _buildFilterChip(context, 'Belum Diterima', - controller.filterStatus.value == 'BELUMMENERIMA'), - ], - ), - ), - - const SizedBox(height: 16), - - // Daftar penerima - gunakan SizedBox dengan height tertentu daripada Expanded - SizedBox( - height: 400, // Tinggi tetap, sesuaikan sesuai kebutuhan - child: Obx(() { - // Tampilkan loading jika sedang memuat ulang data - if (controller.isLoading.value) { - return const Center( - child: CircularProgressIndicator(), - ); - } - - // Tampilkan pesan jika tidak ada data - if (controller.filteredPenerimaPenyaluran.isEmpty) { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon( - Icons.people_outline, - color: Colors.grey, - size: 60, - ), - const SizedBox(height: 16), - const Text( - 'Tidak ada data penerima untuk penyaluran ini', - style: TextStyle(fontSize: 16), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - ElevatedButton( - onPressed: () { - controller.reloadPenerimaPenyaluran(); - }, - child: const Text('Refresh Data'), - ), - ], - ), - ); - } - - // Tampilkan data penerima - return ListView.builder( - itemCount: controller.filteredPenerimaPenyaluran.length, - itemBuilder: (context, index) { - final penerima = controller.filteredPenerimaPenyaluran[index]; - return _buildPenerimaItem(context, penerima); - }, - ); - }), - ), - ], - ), - ); - } - - Widget _buildFilterChip(BuildContext context, String label, bool isSelected) { - String statusValue; - switch (label) { - case 'Sudah Diterima': - statusValue = 'SUDAHMENERIMA'; - break; - case 'Belum Diterima': - statusValue = 'BELUMMENERIMA'; - break; - default: - statusValue = 'SEMUA'; - } - - return FilterChip( - label: Text(label), - selected: isSelected, - onSelected: (selected) { - if (selected) { - controller.filterStatus.value = statusValue; - controller.applyFilters(); - } - }, - 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, - ), - ); - } - - // Metode untuk menampilkan dialog debug - void _showDebugDialog(BuildContext context, Map data) { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('Debug Data'), - content: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Data Struktur:', - style: TextStyle(fontWeight: FontWeight.bold)), - const SizedBox(height: 8), - Text('Keys: ${data.keys.toList().join(', ')}'), - const Divider(), - if (data.containsKey('warga')) ...[ - const Text('Warga Data:', - style: TextStyle(fontWeight: FontWeight.bold)), - const SizedBox(height: 8), - if (data['warga'] != null) - Text( - 'Warga Keys: ${(data['warga'] as Map).keys.toList().join(', ')}') - else - const Text('Warga data is null'), - const Divider(), - ], - const Text('Raw Data:', - style: TextStyle(fontWeight: FontWeight.bold)), - const SizedBox(height: 8), - Text(data.toString(), style: const TextStyle(fontSize: 12)), - ], - ), - ), - actions: [ - TextButton( - onPressed: () => Get.back(), - child: const Text('Tutup'), - ), - ], - ), - ); - } - - // Metode untuk membangun item penerima dengan tombol debug - Widget _buildPenerimaItem( - BuildContext context, Map penerima) { - final bool sudahDiterima = penerima['status_penerimaan'] == 'SUDAHMENERIMA'; - final warga = penerima['warga'] as Map?; - - 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( - warga?['nama_lengkap'] ?? 'Nama tidak tersedia', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 4), - Text('NIK: ${warga?['nik'] ?? 'NIK tidak tersedia'}'), - const SizedBox(height: 2), - Text('Alamat: ${warga?['alamat'] ?? 'Alamat tidak tersedia'}'), - if (penerima['jumlah_bantuan'] != null) ...[ - const SizedBox(height: 2), - Text('Jumlah Bantuan: ${penerima['jumlah_bantuan']}'), - ], - ], - ), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - // Tombol debug untuk melihat struktur data - // IconButton( - // icon: const Icon(Icons.bug_report, color: Colors.grey), - // onPressed: () => _showDebugDialog(context, penerima), - // tooltip: 'Lihat struktur data', - // iconSize: 20, - // ), - 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( - '/konfirmasi-penerima', - arguments: { - 'penerima_id': penerima['id'], - 'penyaluran_id': penerima['penyaluran_bantuan_id'], - 'warga': warga, - 'status_penerimaan': penerima['status_penerimaan'], - 'jumlah_bantuan': penerima['jumlah_bantuan'], - }, - ); - }, - ), - ); - } - - Widget _buildBottomButtons( - BuildContext context, Map jadwal) { - final String status = (jadwal['status'] ?? '').toUpperCase(); - - 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: [ - // Tampilkan tombol berdasarkan status - if (status == 'AKTIF') ...[ - // Tombol Cetak Laporan - Expanded( - child: ElevatedButton.icon( - onPressed: () { - Get.snackbar( - 'Informasi', - 'Mencetak laporan penyaluran...', - snackPosition: SnackPosition.TOP, - ); - }, - 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), - // Tombol Selesaikan - Expanded( - child: ElevatedButton.icon( - onPressed: () { - _showSelesaikanDialog(context, jadwal); - }, - icon: const Icon(Icons.check_circle), - label: const Text('Selesaikan'), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green, - foregroundColor: Colors.white, - padding: const EdgeInsets.symmetric(vertical: 12), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - ), - ), - ] else if (status == 'SELESAI') ...[ - // Hanya tampilkan tombol Cetak Laporan - Expanded( - child: ElevatedButton.icon( - onPressed: () { - Get.snackbar( - 'Informasi', - 'Mencetak laporan penyaluran...', - snackPosition: SnackPosition.TOP, - ); - }, - 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), - ), - ), - ), - ), - ] else if (status == 'DIBATALKAN') ...[ - // Tampilkan pesan dibatalkan - Expanded( - child: Container( - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Colors.red[50], - borderRadius: BorderRadius.circular(8), - ), - child: const Text( - 'Penyaluran Dibatalkan', - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.red, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ] else ...[ - // Status lainnya - tampilkan pesan default - Expanded( - child: Container( - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: Colors.grey[100], - borderRadius: BorderRadius.circular(8), - ), - child: Text( - 'Status: $status', - textAlign: TextAlign.center, - style: const TextStyle( - color: Colors.grey, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ], - ], - ), - ); - } - - void _showSelesaikanDialog( - BuildContext context, Map 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 - controller.completeJadwal(jadwal['id']).then((_) { - Navigator.pop(context); - Get.back(); // Kembali ke halaman sebelumnya - Get.snackbar( - 'Berhasil', - 'Penyaluran telah diselesaikan', - snackPosition: SnackPosition.TOP, - backgroundColor: Colors.green, - colorText: Colors.white, - ); - }).catchError((error) { - Navigator.pop(context); - Get.snackbar( - 'Gagal', - 'Terjadi kesalahan: $error', - snackPosition: SnackPosition.TOP, - backgroundColor: Colors.red, - colorText: Colors.white, - ); - }); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green, - ), - child: const Text('Selesaikan'), - ), - ], - ), - ); - } - - // Metode untuk menampilkan filter dan pencarian - Widget _buildFilterAndSearch(BuildContext context) { - return Container( - padding: const EdgeInsets.all(16), - margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - 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: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Filter & Pencarian', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 16), - // Filter status - Row( - children: [ - const Text('Status: '), - const SizedBox(width: 8), - Expanded( - child: Obx(() { - final currentFilter = controller.filterStatus.value; - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - // Filter Semua - InkWell( - onTap: () => controller.filterStatus.value = 'SEMUA', - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - decoration: BoxDecoration( - color: currentFilter == 'SEMUA' - ? Colors.blue - : Colors.grey[200], - borderRadius: BorderRadius.circular(16), - ), - child: Text( - 'Semua', - style: TextStyle( - color: currentFilter == 'SEMUA' - ? Colors.white - : Colors.black87, - fontWeight: currentFilter == 'SEMUA' - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - ), - const SizedBox(width: 8), - // Filter Sudah Menerima - InkWell( - onTap: () => - controller.filterStatus.value = 'SUDAHMENERIMA', - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - decoration: BoxDecoration( - color: currentFilter == 'SUDAHMENERIMA' - ? Colors.blue - : Colors.grey[200], - borderRadius: BorderRadius.circular(16), - ), - child: Text( - 'Sudah Menerima', - style: TextStyle( - color: currentFilter == 'SUDAHMENERIMA' - ? Colors.white - : Colors.black87, - fontWeight: currentFilter == 'SUDAHMENERIMA' - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - ), - const SizedBox(width: 8), - // Filter Belum Menerima - InkWell( - onTap: () => - controller.filterStatus.value = 'BELUMMENERIMA', - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - decoration: BoxDecoration( - color: currentFilter == 'BELUMMENERIMA' - ? Colors.blue - : Colors.grey[200], - borderRadius: BorderRadius.circular(16), - ), - child: Text( - 'Belum Menerima', - style: TextStyle( - color: currentFilter == 'BELUMMENERIMA' - ? Colors.white - : Colors.black87, - fontWeight: currentFilter == 'BELUMMENERIMA' - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - ), - ], - ), - ); - }), - ), - ], - ), - const SizedBox(height: 16), - // Pencarian - TextField( - onChanged: (value) => controller.searchQuery.value = value, - decoration: InputDecoration( - hintText: 'Cari berdasarkan nama atau NIK', - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - ), - contentPadding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - ), - ), - ], - ), - ); - } - - // Metode untuk menampilkan dialog debug SQL - void _showSqlDebugDialog(BuildContext context, String penyaluranId) { - final validId = controller.ensureValidUUID(penyaluranId); - final sqlQuery = ''' -SELECT - penerima_penyaluran.*, - warga.* -FROM - penerima_penyaluran -LEFT JOIN - warga ON warga.id = penerima_penyaluran.warga_id -WHERE - penerima_penyaluran.penyaluran_bantuan_id = '$validId'; -'''; - - showDialog( - context: context, - builder: (context) => AlertDialog( - title: const Text('SQL Query Debug'), - content: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - const Text('SQL Query yang digunakan:'), - const SizedBox(height: 8), - Container( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(8), - ), - child: SelectableText( - sqlQuery, - style: const TextStyle( - fontFamily: 'monospace', - fontSize: 12, - ), - ), - ), - const SizedBox(height: 16), - const Text('Petunjuk:'), - const SizedBox(height: 8), - const Text('1. Salin query ini ke SQL Editor di Supabase'), - const Text('2. Jalankan query untuk melihat hasil'), - const Text( - '3. Bandingkan dengan data yang ditampilkan di aplikasi'), - ], - ), - ), - actions: [ - TextButton( - onPressed: () => Get.back(), - child: const Text('Tutup'), - ), - ], - ), - ); - } -} diff --git a/lib/app/modules/petugas_desa/views/petugas_desa_view.dart b/lib/app/modules/petugas_desa/views/petugas_desa_view.dart index 51fbfbc..9be5f87 100644 --- a/lib/app/modules/petugas_desa/views/petugas_desa_view.dart +++ b/lib/app/modules/petugas_desa/views/petugas_desa_view.dart @@ -378,10 +378,6 @@ class PetugasDesaView extends GetView { } Widget _buildBottomNavigationBar() { - // Tambahkan print statement untuk debugging - print('Jumlah pengaduan diproses: ${controller.jumlahDiproses.value}'); - print('Jumlah jadwal hari ini: ${controller.jadwalHariIni.length}'); - return Obx(() { return BottomNavigationBar( currentIndex: controller.activeTabIndex.value, diff --git a/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart b/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart index 6a2e002..76c1823 100644 --- a/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart +++ b/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart @@ -221,79 +221,75 @@ class TambahPenyaluranView extends GetView { selectedSkemaBantuanId.value ?? '') .eq('status', 'TERVERIFIKASI'); - if (pengajuanData != null) { - Get.dialog( - Dialog( - child: Container( - width: MediaQuery.of(context).size.width * 0.9, - height: - MediaQuery.of(context).size.height * 0.8, - padding: const EdgeInsets.all(16), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - const Text( - 'Daftar Penerima Bantuan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + Get.dialog( + Dialog( + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + height: MediaQuery.of(context).size.height * 0.8, + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Daftar Penerima Bantuan', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, ), - IconButton( - onPressed: () => Get.back(), - icon: const Icon(Icons.close), - ), - ], - ), - const SizedBox(height: 16), - Expanded( + ), + IconButton( + onPressed: () => Get.back(), + icon: const Icon(Icons.close), + ), + ], + ), + const SizedBox(height: 16), + Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: SingleChildScrollView( - child: DataTable( - columnSpacing: 20, - horizontalMargin: 20, - columns: const [ - DataColumn(label: Text('No')), - DataColumn(label: Text('Nama')), - DataColumn(label: Text('NIK')), - DataColumn(label: Text('Alamat')), - ], - rows: pengajuanData - .asMap() - .entries - .map((entry) { - final warga = - entry.value['warga']; - return DataRow( - cells: [ - DataCell( - Text('${entry.key + 1}')), - DataCell(Text( - warga['nama_lengkap'] ?? - '-')), - DataCell(Text( - warga['nik'] ?? '-')), - DataCell(Text( - warga['alamat'] ?? '-')), - ], - ); - }).toList(), - ), + child: DataTable( + columnSpacing: 20, + horizontalMargin: 20, + columns: const [ + DataColumn(label: Text('No')), + DataColumn(label: Text('Nama')), + DataColumn(label: Text('NIK')), + DataColumn(label: Text('Alamat')), + ], + rows: pengajuanData + .asMap() + .entries + .map((entry) { + final warga = entry.value['warga']; + return DataRow( + cells: [ + DataCell( + Text('${entry.key + 1}')), + DataCell(Text( + warga['nama_lengkap'] ?? + '-')), + DataCell( + Text(warga['nik'] ?? '-')), + DataCell(Text( + warga['alamat'] ?? '-')), + ], + ); + }).toList(), ), ), ), - ], - ), + ), + ], ), ), - ); - } + ), + ); }, icon: const Icon(Icons.people), label: const Text('Lihat Daftar Penerima'), diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index f41eba7..c75247f 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -7,7 +7,6 @@ import 'package:penyaluran_app/app/modules/petugas_desa/views/permintaan_penjadw 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/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/views/riwayat_penitipan_view.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/views/daftar_donatur_view.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/views/detail_donatur_view.dart'; @@ -63,11 +62,6 @@ class AppPages { page: () => const KonfirmasiPenerimaView(), binding: PenerimaBinding(), ), - GetPage( - name: _Paths.pelaksanaanPenyaluran, - page: () => const PelaksanaanPenyaluranView(), - binding: PetugasDesaBinding(), - ), GetPage( name: _Paths.profile, page: () => const ProfileView(), diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index f0f6db5..ed144c1 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -20,6 +20,9 @@ abstract class Routes { static const daftarDonatur = _Paths.daftarDonatur; static const detailDonatur = _Paths.detailDonatur; static const tambahPenyaluran = _Paths.tambahPenyaluran; + static const daftarPenerimaPenyaluran = _Paths.daftarPenerimaPenyaluran; + static const detailPenerimaPenyaluran = _Paths.detailPenerimaPenyaluran; + static const laporanPenyaluran = _Paths.laporanPenyaluran; } abstract class _Paths { @@ -42,4 +45,7 @@ abstract class _Paths { static const daftarDonatur = '/daftar-donatur'; static const detailDonatur = '/daftar-donatur/detail'; static const tambahPenyaluran = '/tambah-penyaluran'; + static const daftarPenerimaPenyaluran = '/daftar-penerima-penyaluran'; + static const detailPenerimaPenyaluran = '/detail-penerima-penyaluran'; + static const laporanPenyaluran = '/laporan-penyaluran'; } diff --git a/lib/app/services/supabase_service.dart b/lib/app/services/supabase_service.dart index fcea23f..4e477b7 100644 --- a/lib/app/services/supabase_service.dart +++ b/lib/app/services/supabase_service.dart @@ -1,7 +1,6 @@ import 'package:get/get.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'dart:io'; -import 'package:penyaluran_app/app/utils/date_time_helper.dart'; class SupabaseService extends GetxService { static SupabaseService get to => Get.find();