From eede5ebd4d9d0dbcbb6eee48068acac917c6c76d Mon Sep 17 00:00:00 2001 From: Khafidh Fuadi Date: Wed, 26 Mar 2025 09:57:13 +0700 Subject: [PATCH] Perbarui beberapa file konfigurasi fingerprint untuk arsitektur arm64-v8a, armeabi-v7a, x86, dan x86_64. Modifikasi model SkemaBantuan untuk menggunakan operator null-aware pada jumlah diterima per orang. Perbarui logika pengambilan data di AuthProvider untuk menyederhanakan pengecekan dan logging. Tambahkan fungsionalitas baru di DonaturDashboardController untuk mengunggah foto bantuan dan memperbarui data yang disimpan. Hapus tampilan yang tidak digunakan di DonaturRiwayatPenitipanView dan perbarui tampilan di beberapa view untuk meningkatkan pengalaman pengguna. --- .../arm64-v8a/configure_fingerprint.bin | 24 +- .../armeabi-v7a/configure_fingerprint.bin | 24 +- .../626b5o2n/x86/configure_fingerprint.bin | 24 +- .../626b5o2n/x86_64/configure_fingerprint.bin | 24 +- lib/app/data/models/skema_bantuan_model.dart | 4 +- lib/app/data/providers/auth_provider.dart | 74 +-- .../donatur_dashboard_controller.dart | 16 +- .../donatur/views/donatur_penitipan_view.dart | 438 +-------------- .../views/donatur_riwayat_penitipan_view.dart | 511 +++++++++++++----- .../donatur/views/donatur_skema_view.dart | 1 - .../modules/donatur/views/donatur_view.dart | 1 + .../laporan_penyaluran_controller.dart | 9 +- .../views/laporan_penyaluran_create_view.dart | 2 +- .../views/laporan_penyaluran_detail_view.dart | 11 +- .../views/laporan_penyaluran_edit_view.dart | 2 +- .../views/laporan_penyaluran_view.dart | 2 +- .../detail_penyaluran_controller.dart | 72 +-- .../jadwal_penyaluran_controller.dart | 2 +- .../penitipan_bantuan_controller.dart | 56 +- .../controllers/petugas_desa_controller.dart | 4 +- .../petugas_desa/views/dashboard_view.dart | 1 - .../views/detail_donatur_view.dart | 1 - .../views/detail_penerima_view.dart | 1 - .../views/konfirmasi_penerima_page.dart | 4 +- .../petugas_desa/views/penitipan_view.dart | 12 +- .../petugas_desa/views/stok_bantuan_view.dart | 4 +- .../views/tambah_penyaluran_view.dart | 29 +- .../controllers/profile_controller.dart | 1 - .../modules/profile/views/profile_view.dart | 2 +- .../warga_dashboard_controller.dart | 2 +- .../warga/views/warga_dashboard_view.dart | 2 +- .../views/warga_detail_penerimaan_view.dart | 1 - lib/app/services/supabase_service.dart | 32 +- 33 files changed, 600 insertions(+), 793 deletions(-) diff --git a/android/app/.cxx/Debug/626b5o2n/arm64-v8a/configure_fingerprint.bin b/android/app/.cxx/Debug/626b5o2n/arm64-v8a/configure_fingerprint.bin index 1196bbf..46ce618 100644 --- a/android/app/.cxx/Debug/626b5o2n/arm64-v8a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/626b5o2n/arm64-v8a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured LogO M KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2 +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2  -}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\additional_project_files.txt  2  2~ +}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\additional_project_files.txt  2  2~ | -zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build.json  2 2 +zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build.json  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build_mini.json  2 2p +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build_mini.json  2 2p n -lD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja  2 2t +lD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja  2 2t r -pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja.txt  2y +pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja.txt  2y w -uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build_file_index.txt  2 K 2z +uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build_file_index.txt  2 K 2z x -vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json  2 ~ +vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json  2 ~ | -zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json.bin  2 +zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\metadata_generation_command.txt  2  2w +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\metadata_generation_command.txt  2  2w u -sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\prefab_config.json  2  ( 2| +sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\prefab_config.json  2  ( 2| z -xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\symbol_folder_index.txt  2  o 2 \ No newline at end of file +xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\symbol_folder_index.txt  2  o 2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/626b5o2n/armeabi-v7a/configure_fingerprint.bin b/android/app/.cxx/Debug/626b5o2n/armeabi-v7a/configure_fingerprint.bin index 6506592..ac89689 100644 --- a/android/app/.cxx/Debug/626b5o2n/armeabi-v7a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/626b5o2n/armeabi-v7a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured LogO M KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2 +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\additional_project_files.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\additional_project_files.txt  2  2 ~ -|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build.json  2 2 +|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build.json  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build_mini.json  2 2r +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build_mini.json  2 2r p -nD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja  2 2v +nD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja  2 2v t -rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja.txt  2{ +rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja.txt  2{ y -wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build_file_index.txt  2 K 2| +wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build_file_index.txt  2 K 2| z -xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json  2  +xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json  2  ~ -|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json.bin  2 +|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\metadata_generation_command.txt  2  2y +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\metadata_generation_command.txt  2  2y w -uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\prefab_config.json  2  ( 2~ +uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\prefab_config.json  2  ( 2~ | -zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\symbol_folder_index.txt  2  q 2 \ No newline at end of file +zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\symbol_folder_index.txt  2  q 2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/626b5o2n/x86/configure_fingerprint.bin b/android/app/.cxx/Debug/626b5o2n/x86/configure_fingerprint.bin index 5c0cdfe..40d2710 100644 --- a/android/app/.cxx/Debug/626b5o2n/x86/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/626b5o2n/x86/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured LogO M KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2{ +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2{ y -wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\additional_project_files.txt  2  2x +wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\additional_project_files.txt  2  2x v -tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build.json  2 2} +tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build.json  2 2} { -yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build_mini.json  2 2j +yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build_mini.json  2 2j h -fD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja  2 2n +fD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja  2 2n l -jD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja.txt  2s +jD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja.txt  2s q -oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build_file_index.txt  2 K 2t +oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build_file_index.txt  2 K 2t r -pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json  2 x +pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json  2 x v -tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json.bin  2 +tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json.bin  2 ~ | -zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\metadata_generation_command.txt  2  2q +zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\metadata_generation_command.txt  2  2q o -mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\prefab_config.json  2  ( 2v +mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\prefab_config.json  2  ( 2v t -rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\symbol_folder_index.txt  2  i 2 \ No newline at end of file +rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\symbol_folder_index.txt  2  i 2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin b/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin index 0c01600..062fca2 100644 --- a/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured LogO M KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ِ2 2~ +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2 2~ | -zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt  ِ2  2{ +zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt  2  2{ y -wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json  ِ2 2 +wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json  2 2 ~ -|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json  ِ2 2m +|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json  2 2m k -iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja  ِ2 2q +iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja  2 2q o -mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt  ِ2v +mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt  2v t -rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt  ِ2 K 2w +rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt  2 K 2w u -sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json  ِ2 { +sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json  2 { y -wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin  ِ2 +wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin  2   -}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt  ِ2  2t +}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt  2  2t r -pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json  ِ2  ( 2y +pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json  2  ( 2y w -uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\symbol_folder_index.txt  ِ2  l 2 \ No newline at end of file +uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\symbol_folder_index.txt  2  l 2 \ No newline at end of file diff --git a/lib/app/data/models/skema_bantuan_model.dart b/lib/app/data/models/skema_bantuan_model.dart index 9d19e54..750185d 100644 --- a/lib/app/data/models/skema_bantuan_model.dart +++ b/lib/app/data/models/skema_bantuan_model.dart @@ -48,9 +48,7 @@ class SkemaBantuanModel { : null, stokBantuanId: json["stok_bantuan_id"], kategoriBantuanId: json["kategori_bantuan_id"], - jumlahDiterimaPerOrang: json["jumlah_diterima_per_orang"] != null - ? json["jumlah_diterima_per_orang"].toDouble() - : null, + jumlahDiterimaPerOrang: json["jumlah_diterima_per_orang"]?.toDouble(), ); Map toJson() => { diff --git a/lib/app/data/providers/auth_provider.dart b/lib/app/data/providers/auth_provider.dart index 39fae41..8e2dfc8 100644 --- a/lib/app/data/providers/auth_provider.dart +++ b/lib/app/data/providers/auth_provider.dart @@ -89,19 +89,14 @@ class AuthProvider { .eq('id', userId) .single(); - if (profileResponse != null) { - // Ekstrak data desa jika ada - if (profileResponse['desa'] != null) { - desa = DesaModel.fromJson(profileResponse['desa']); - print('Data Desa: ${desa.nama}'); - } - - roleData = WargaModel.fromJson(profileResponse); - print('Data Warga: ${roleData.namaLengkap}'); - } else { - print('Tidak menemukan data warga untuk ID: $userId'); - return null; + // Ekstrak data desa jika ada + if (profileResponse['desa'] != null) { + desa = DesaModel.fromJson(profileResponse['desa']); + print('Data Desa: ${desa.nama}'); } + + roleData = WargaModel.fromJson(profileResponse); + print('Data Warga: ${roleData.namaLengkap}'); } else if (roleName == 'petugas_desa') { profileResponse = await _supabaseService.client .from('petugas_desa') @@ -109,17 +104,15 @@ class AuthProvider { .eq('id', userId) .single(); - if (profileResponse != null) { - // Ekstrak data desa jika ada - if (profileResponse['desa'] != null) { - desa = DesaModel.fromJson(profileResponse['desa']); - print('Data Desa: ${desa.nama}'); - } - - roleData = PetugasDesaModel.fromJson(profileResponse); - print( - 'Data Petugas Desa: ${roleData.namaLengkap}, Desa: ${roleData.desa?.nama}'); + // Ekstrak data desa jika ada + if (profileResponse['desa'] != null) { + desa = DesaModel.fromJson(profileResponse['desa']); + print('Data Desa: ${desa.nama}'); } + + roleData = PetugasDesaModel.fromJson(profileResponse); + print( + 'Data Petugas Desa: ${roleData.namaLengkap}, Desa: ${roleData.desa?.nama}'); } else if (roleName == 'donatur') { profileResponse = await _supabaseService.client .from('donatur') @@ -252,19 +245,14 @@ class AuthProvider { .eq('id', userId) .single(); - if (profileResponse != null) { - // Ekstrak data desa jika ada - if (profileResponse['desa'] != null) { - desa = DesaModel.fromJson(profileResponse['desa']); - print('Data Desa: ${desa.nama}'); - } - - roleData = WargaModel.fromJson(profileResponse); - print('Data Warga: ${roleData.namaLengkap}'); - } else { - print('Tidak menemukan data warga untuk ID: $userId'); - return null; + // Ekstrak data desa jika ada + if (profileResponse['desa'] != null) { + desa = DesaModel.fromJson(profileResponse['desa']); + print('Data Desa: ${desa.nama}'); } + + roleData = WargaModel.fromJson(profileResponse); + print('Data Warga: ${roleData.namaLengkap}'); } else if (roleName.toLowerCase() == 'petugas_desa') { profileResponse = await _supabaseService.client .from('petugas_desa') @@ -273,15 +261,13 @@ class AuthProvider { .eq('id', userId) .single(); - if (profileResponse != null) { - // Ekstrak data desa jika ada - if (profileResponse['desa'] != null) { - desa = DesaModel.fromJson(profileResponse['desa']); - print('Data Desa: ${desa.nama}'); - } - - roleData = PetugasDesaModel.fromJson(profileResponse); + // Ekstrak data desa jika ada + if (profileResponse['desa'] != null) { + desa = DesaModel.fromJson(profileResponse['desa']); + print('Data Desa: ${desa.nama}'); } + + roleData = PetugasDesaModel.fromJson(profileResponse); } else if (roleName.toLowerCase() == 'donatur') { profileResponse = await _supabaseService.client .from('donatur') @@ -289,9 +275,7 @@ class AuthProvider { .eq('id', userId) .single(); - if (profileResponse != null) { - roleData = DonaturModel.fromJson(profileResponse); - } + roleData = DonaturModel.fromJson(profileResponse); } if (roleData == null) { diff --git a/lib/app/modules/donatur/controllers/donatur_dashboard_controller.dart b/lib/app/modules/donatur/controllers/donatur_dashboard_controller.dart index 45c9302..a047441 100644 --- a/lib/app/modules/donatur/controllers/donatur_dashboard_controller.dart +++ b/lib/app/modules/donatur/controllers/donatur_dashboard_controller.dart @@ -401,9 +401,19 @@ class DonaturDashboardController extends GetxController { throw Exception('Foto bantuan harus diunggah'); } + // Dapatkan informasi stok bantuan untuk mendapatkan nilai is_uang + final selectedStokBantuan = stokBantuan.firstWhere( + (stok) => stok.id == stokBantuanId, + orElse: () => StokBantuanModel(), + ); + // Unggah foto bantuan ke storage menggunakan metode dari SupabaseService final fotoBantuanUrls = await _supabaseService.uploadMultipleFiles( - fotoBantuanPaths, 'penitipan', 'foto_bantuan'); + fotoBantuanPaths, 'bantuan', 'foto_bantuan'); + + if (fotoBantuanUrls == null || fotoBantuanUrls.isEmpty) { + throw 'Gagal mengupload foto bantuan'; + } // Data yang akan disimpan final Map data = { @@ -414,6 +424,7 @@ class DonaturDashboardController extends GetxController { 'status': 'MENUNGGU', 'tanggal_penitipan': DateTime.now().toIso8601String(), 'foto_bantuan': fotoBantuanUrls, + 'is_uang': selectedStokBantuan.isUang ?? false, }; // Tambahkan skema bantuan jika ada @@ -438,9 +449,6 @@ class DonaturDashboardController extends GetxController { colorText: Colors.white, duration: const Duration(seconds: 3), ); - - // Pindah ke tab riwayat penitipan - DefaultTabController.of(Get.context!)?.animateTo(0); } catch (e) { print('Error creating penitipan bantuan: $e'); Get.snackbar( diff --git a/lib/app/modules/donatur/views/donatur_penitipan_view.dart b/lib/app/modules/donatur/views/donatur_penitipan_view.dart index f3cb54d..b4195ba 100644 --- a/lib/app/modules/donatur/views/donatur_penitipan_view.dart +++ b/lib/app/modules/donatur/views/donatur_penitipan_view.dart @@ -25,443 +25,9 @@ class DonaturPenitipanView extends GetView { } } -class DonaturRiwayatPenitipanView extends GetView { - DonaturRiwayatPenitipanView({Key? key}) : super(key: key); - - @override - DonaturDashboardController get controller { - return Get.find(tag: 'donatur_dashboard'); - } - - final TextEditingController searchController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return DefaultTabController( - length: 3, - child: Scaffold( - appBar: AppBar( - title: const Text('Riwayat Penitipan'), - bottom: const TabBar( - tabs: [ - Tab(text: 'Menunggu'), - Tab(text: 'Diterima'), - Tab(text: 'Ditolak'), - ], - ), - ), - body: TabBarView( - children: [ - // Tab Menunggu - _buildPenitipanList(context, 'MENUNGGU'), - // Tab Diterima - _buildPenitipanList(context, 'DITERIMA'), - // Tab Ditolak - _buildPenitipanList(context, 'DITOLAK'), - ], - ), - ), - ); - } - - Widget _buildPenitipanList(BuildContext context, String status) { - return Obx(() { - if (controller.isLoading.value) { - return const Center(child: CircularProgressIndicator()); - } - - // Filter penitipan berdasarkan status - var filteredList = controller.penitipanBantuan - .where((item) => item.status == status) - .toList(); - - // Filter berdasarkan pencarian - final searchText = searchController.text.toLowerCase(); - if (searchText.isNotEmpty) { - filteredList = filteredList.where((item) { - final kategoriNama = item.kategoriBantuan?.nama?.toLowerCase() ?? ''; - final deskripsi = item.deskripsi?.toLowerCase() ?? ''; - final tanggal = item.tanggalPenitipan != null - ? DateFormat('dd MMMM yyyy', 'id_ID') - .format(item.tanggalPenitipan!) - .toLowerCase() - : ''; - - return kategoriNama.contains(searchText) || - deskripsi.contains(searchText) || - tanggal.contains(searchText); - }).toList(); - } - - return RefreshIndicator( - onRefresh: () async { - await controller.fetchPenitipanBantuan(); - }, - child: filteredList.isEmpty - ? _buildEmptyState(status) - : _buildContentList(context, filteredList, status), - ); - }); - } - - Widget _buildEmptyState(String status) { - String statusText = ''; - switch (status) { - case 'MENUNGGU': - statusText = 'menunggu verifikasi'; - break; - case 'DITERIMA': - statusText = 'diterima'; - break; - case 'DITOLAK': - statusText = 'ditolak'; - break; - } - - return Center( - child: SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.inventory_2_outlined, - size: 80, - color: Colors.grey.shade400, - ), - const SizedBox(height: 16), - Text( - 'Tidak ada penitipan $statusText', - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 8), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32), - child: Text( - 'Anda belum memiliki riwayat penitipan yang $statusText', - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - textAlign: TextAlign.center, - ), - ), - ], - ), - ), - ); - } - - Widget _buildContentList( - BuildContext context, List filteredList, String status) { - Color statusColor; - switch (status) { - case 'DITERIMA': - statusColor = Colors.green; - break; - case 'DITOLAK': - statusColor = Colors.red; - break; - case 'MENUNGGU': - default: - statusColor = Colors.orange; - break; - } - - return SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Search field - TextField( - controller: searchController, - decoration: InputDecoration( - hintText: 'Cari riwayat penitipan...', - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: BorderSide.none, - ), - filled: true, - fillColor: Colors.grey.shade100, - contentPadding: const EdgeInsets.symmetric(vertical: 0), - ), - onChanged: (value) { - // Trigger update dengan GetX - controller.update(); - }, - ), - const SizedBox(height: 16), - // Info jumlah item - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Daftar Penitipan ${status.toLowerCase()}', - style: Theme.of(context).textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Text( - '${filteredList.length} item', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Colors.grey, - ), - ), - ], - ), - const SizedBox(height: 16), - // Daftar penitipan - ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: filteredList.length, - itemBuilder: (context, index) { - return _buildPenitipanCard( - context, filteredList[index], statusColor); - }, - ), - ], - ), - ), - ); - } - - Widget _buildPenitipanCard( - BuildContext context, dynamic penitipan, Color statusColor) { - final formattedDate = penitipan.tanggalPenitipan != null - ? DateFormat('dd MMMM yyyy', 'id_ID') - .format(penitipan.tanggalPenitipan!) - : 'Tanggal tidak tersedia'; - - IconData statusIcon; - - switch (penitipan.status) { - case 'DITERIMA': - statusIcon = Icons.check_circle; - break; - case 'DITOLAK': - statusIcon = Icons.cancel; - break; - case 'MENUNGGU': - default: - statusIcon = Icons.hourglass_empty; - break; - } - - return Container( - margin: const EdgeInsets.only(bottom: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 10, - offset: const Offset(0, 5), - ), - ], - ), - child: Card( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: statusColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - statusIcon, - color: statusColor, - size: 24, - ), - ), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - penitipan.kategoriBantuan?.nama ?? 'Bantuan', - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: statusColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(12), - ), - child: Text( - penitipan.status ?? 'MENUNGGU', - style: TextStyle( - fontSize: 12, - color: statusColor, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - const SizedBox(height: 4), - Row( - children: [ - Icon( - Icons.calendar_today, - size: 14, - color: Colors.grey.shade600, - ), - const SizedBox(width: 4), - Text( - formattedDate, - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ), - ], - ), - const SizedBox(height: 4), - Row( - children: [ - Icon( - Icons.inventory_2_outlined, - size: 14, - color: Colors.grey.shade600, - ), - const SizedBox(width: 4), - Text( - 'Jumlah: ${penitipan.jumlah ?? 0}', - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade800, - ), - ), - ], - ), - ], - ), - ), - ], - ), - if (penitipan.deskripsi != null && - penitipan.deskripsi!.isNotEmpty) ...[ - const Divider(height: 24), - Text( - penitipan.deskripsi!, - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade700, - ), - maxLines: 3, - overflow: TextOverflow.ellipsis, - ), - ], - if (penitipan.status == 'DITOLAK' && - penitipan.alasanPenolakan != null && - penitipan.alasanPenolakan!.isNotEmpty) ...[ - const Divider(height: 24), - Text( - 'Alasan Penolakan:', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.red.shade700, - ), - ), - const SizedBox(height: 4), - Text( - penitipan.alasanPenolakan!, - style: TextStyle( - fontSize: 14, - color: Colors.red.shade700, - ), - ), - ], - ], - ), - ), - ), - ); - } - - Widget _buildContactInfo({ - required IconData icon, - required String title, - required String content, - }) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: Colors.blue.shade50, - borderRadius: BorderRadius.circular(8), - ), - child: Icon( - icon, - color: Colors.blue, - size: 20, - ), - ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 4), - Text( - content, - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade700, - ), - ), - ], - ), - ), - ], - ); - } -} - class FormPenitipanBantuan extends StatefulWidget { + const FormPenitipanBantuan({super.key}); + @override _FormPenitipanBantuanState createState() => _FormPenitipanBantuanState(); } diff --git a/lib/app/modules/donatur/views/donatur_riwayat_penitipan_view.dart b/lib/app/modules/donatur/views/donatur_riwayat_penitipan_view.dart index f32ceda..fcffda9 100644 --- a/lib/app/modules/donatur/views/donatur_riwayat_penitipan_view.dart +++ b/lib/app/modules/donatur/views/donatur_riwayat_penitipan_view.dart @@ -4,7 +4,7 @@ import 'package:intl/intl.dart'; import 'package:penyaluran_app/app/modules/donatur/controllers/donatur_dashboard_controller.dart'; class DonaturRiwayatPenitipanView extends GetView { - DonaturRiwayatPenitipanView({Key? key}) : super(key: key); + DonaturRiwayatPenitipanView({super.key}); @override DonaturDashboardController get controller { @@ -23,7 +23,7 @@ class DonaturRiwayatPenitipanView extends GetView { bottom: const TabBar( tabs: [ Tab(text: 'Menunggu'), - Tab(text: 'Diterima'), + Tab(text: 'Terverifikasi'), Tab(text: 'Ditolak'), ], ), @@ -33,7 +33,7 @@ class DonaturRiwayatPenitipanView extends GetView { // Tab Menunggu _buildPenitipanList(context, 'MENUNGGU'), // Tab Diterima - _buildPenitipanList(context, 'DITERIMA'), + _buildPenitipanList(context, 'TERVERIFIKASI'), // Tab Ditolak _buildPenitipanList(context, 'DITOLAK'), ], @@ -88,8 +88,8 @@ class DonaturRiwayatPenitipanView extends GetView { case 'MENUNGGU': statusText = 'menunggu verifikasi'; break; - case 'DITERIMA': - statusText = 'diterima'; + case 'TERVERIFIKASI': + statusText = 'terverifikasi'; break; case 'DITOLAK': statusText = 'ditolak'; @@ -137,7 +137,7 @@ class DonaturRiwayatPenitipanView extends GetView { BuildContext context, List filteredList, String status) { Color statusColor; switch (status) { - case 'DITERIMA': + case 'TERVERIFIKASI': statusColor = Colors.green; break; case 'DITOLAK': @@ -221,7 +221,7 @@ class DonaturRiwayatPenitipanView extends GetView { IconData statusIcon; switch (penitipan.status) { - case 'DITERIMA': + case 'TERVERIFIKASI': statusIcon = Icons.check_circle; break; case 'DITOLAK': @@ -233,160 +233,397 @@ class DonaturRiwayatPenitipanView extends GetView { break; } - return Container( - margin: const EdgeInsets.only(bottom: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 10, - offset: const Offset(0, 5), + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + print('Debug: Tapped on penitipan with ID: ${penitipan.id}'); + _showDetailDialog(context, penitipan); + }, + child: Container( + margin: const EdgeInsets.only(bottom: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 5), + ), + ], ), - ], - ), - child: Card( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + child: Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 50, - height: 50, - alignment: Alignment.center, - decoration: BoxDecoration( - color: statusColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - statusIcon, - color: statusColor, - size: 24, - ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: statusColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + statusIcon, + color: statusColor, + size: 24, + ), + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + penitipan.kategoriBantuan?.nama ?? + 'Bantuan', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: statusColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + penitipan.status ?? 'MENUNGGU', + style: TextStyle( + fontSize: 12, + color: statusColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const SizedBox(height: 4), + Row( + children: [ + Icon( + Icons.calendar_today, + size: 14, + color: Colors.grey.shade600, + ), + const SizedBox(width: 4), + Text( + formattedDate, + style: TextStyle( + fontSize: 14, + color: Colors.grey.shade600, + ), + ), + ], + ), + const SizedBox(height: 4), + Row( + children: [ + Icon( + Icons.inventory_2_outlined, + size: 14, + color: Colors.grey.shade600, + ), + const SizedBox(width: 4), + Text( + 'Jumlah: ${penitipan.jumlah ?? 0}', + style: TextStyle( + fontSize: 14, + color: Colors.grey.shade800, + ), + ), + ], + ), + ], + ), + ), + ], ), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - penitipan.kategoriBantuan?.nama ?? 'Bantuan', - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + if (penitipan.deskripsi != null && + penitipan.deskripsi!.isNotEmpty) ...[ + const Divider(height: 24), + Text( + penitipan.deskripsi!, + style: TextStyle( + fontSize: 14, + color: Colors.grey.shade700, + ), + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + ], + if (penitipan.status == 'DITOLAK' && + penitipan.alasanPenolakan != null && + penitipan.alasanPenolakan!.isNotEmpty) ...[ + const Divider(height: 24), + Text( + 'Alasan Penolakan:', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.red.shade700, + ), + ), + const SizedBox(height: 4), + Text( + penitipan.alasanPenolakan!, + style: TextStyle( + fontSize: 14, + color: Colors.red.shade700, + ), + ), + ], + // Tambahkan petunjuk visual + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: const EdgeInsets.only(top: 8), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.info_outline, + size: 14, + color: Colors.blue.shade700, + ), + const SizedBox(width: 4), + Text( + 'Tap untuk detail', + style: TextStyle( + fontSize: 12, + color: Colors.blue.shade700, + fontStyle: FontStyle.italic, ), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: statusColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(12), - ), - child: Text( - penitipan.status ?? 'MENUNGGU', - style: TextStyle( - fontSize: 12, - color: statusColor, - fontWeight: FontWeight.bold, - ), - ), - ), - ], - ), - const SizedBox(height: 4), - Row( - children: [ - Icon( - Icons.calendar_today, - size: 14, - color: Colors.grey.shade600, - ), - const SizedBox(width: 4), - Text( - formattedDate, - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ), - ], - ), - const SizedBox(height: 4), - Row( - children: [ - Icon( - Icons.inventory_2_outlined, - size: 14, - color: Colors.grey.shade600, - ), - const SizedBox(width: 4), - Text( - 'Jumlah: ${penitipan.jumlah ?? 0}', - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade800, - ), - ), - ], - ), - ], + ), + ], + ), ), ), ], ), - if (penitipan.deskripsi != null && - penitipan.deskripsi!.isNotEmpty) ...[ - const Divider(height: 24), - Text( - penitipan.deskripsi!, - style: TextStyle( - fontSize: 14, - color: Colors.grey.shade700, + ), + ), + ), + ), + ); + } + + void _showDetailDialog(BuildContext context, dynamic penitipan) { + final isUang = penitipan.isUang ?? false; + final kategoriSatuan = penitipan.kategoriBantuan?.satuan ?? ''; + + String getPetugasDesaNama(String? id) { + return id != null ? 'Petugas Desa' : 'Tidak ada petugas'; + } + + void showFullScreenImage(String imageUrl) { + Get.dialog( + Dialog( + insetPadding: EdgeInsets.zero, + child: Container( + color: Colors.black, + child: Stack( + fit: StackFit.expand, + children: [ + InteractiveViewer( + panEnabled: true, + minScale: 0.5, + maxScale: 4, + child: Image.network( + imageUrl, + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + ), + ); + }, + ), + ), + Positioned( + top: 20, + right: 20, + child: GestureDetector( + onTap: () => Get.back(), + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.5), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.close, + color: Colors.white, + size: 24, + ), + ), ), - maxLines: 3, - overflow: TextOverflow.ellipsis, ), ], - if (penitipan.status == 'DITOLAK' && - penitipan.alasanPenolakan != null && - penitipan.alasanPenolakan!.isNotEmpty) ...[ - const Divider(height: 24), - Text( - 'Alasan Penolakan:', + ), + ), + ), + ); + } + + Get.dialog( + AlertDialog( + title: const Text('Detail Penitipan'), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildInfoRow('ID', penitipan.id ?? '-'), + _buildInfoRow('Kategori', penitipan.kategoriBantuan?.nama ?? '-'), + _buildInfoRow( + 'Jumlah', + isUang + ? 'Rp ${penitipan.jumlah?.toStringAsFixed(0) ?? '0'}' + : '${penitipan.jumlah?.toString() ?? '0'} $kategoriSatuan', + ), + _buildInfoRow( + 'Tanggal Penitipan', + penitipan.tanggalPenitipan != null + ? DateFormat('dd MMMM yyyy', 'id_ID') + .format(penitipan.tanggalPenitipan!) + : 'Tanggal tidak tersedia', + ), + _buildInfoRow( + 'Status', + penitipan.status ?? 'Belum diproses', + ), + if (penitipan.tanggalVerifikasi != null) + _buildInfoRow( + 'Tanggal Verifikasi', + DateFormat('dd MMMM yyyy HH:mm', 'id_ID') + .format(penitipan.tanggalVerifikasi!), + ), + if (penitipan.deskripsi != null && + penitipan.deskripsi!.isNotEmpty) + _buildInfoRow('Deskripsi', penitipan.deskripsi!), + if (penitipan.alasanPenolakan != null && + penitipan.alasanPenolakan!.isNotEmpty) + _buildInfoRow('Alasan Penolakan', penitipan.alasanPenolakan!), + + // Gambar bukti penitipan + if (penitipan.fotoBantuan != null && + penitipan.fotoBantuan!.isNotEmpty) ...[ + const SizedBox(height: 16), + const Text( + 'Bukti Penitipan', style: TextStyle( - fontSize: 14, fontWeight: FontWeight.bold, - color: Colors.red.shade700, + fontSize: 14, ), ), - const SizedBox(height: 4), - Text( - penitipan.alasanPenolakan!, + const SizedBox(height: 8), + GestureDetector( + onTap: () => + showFullScreenImage(penitipan.fotoBantuan!.first), + child: Container( + height: 200, + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: NetworkImage(penitipan.fotoBantuan!.first), + fit: BoxFit.cover, + ), + ), + ), + ), + ], + + // Bukti serah terima jika ada + if (penitipan.fotoBuktiSerahTerima != null && + penitipan.fotoBuktiSerahTerima!.isNotEmpty) ...[ + const SizedBox(height: 16), + const Text( + 'Bukti Serah Terima', style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 14, - color: Colors.red.shade700, + ), + ), + const SizedBox(height: 8), + GestureDetector( + onTap: () => + showFullScreenImage(penitipan.fotoBuktiSerahTerima!), + child: Container( + height: 200, + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + image: NetworkImage(penitipan.fotoBuktiSerahTerima!), + fit: BoxFit.cover, + ), + ), ), ), ], ], ), ), + actions: [ + TextButton( + onPressed: () => Get.back(), + child: const Text( + 'Tutup', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ); + } + + Widget _buildInfoRow(String label, String value) { + return Padding( + padding: const EdgeInsets.only(bottom: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + Text( + value, + style: const TextStyle(fontSize: 14), + ), + ], ), ); } diff --git a/lib/app/modules/donatur/views/donatur_skema_view.dart b/lib/app/modules/donatur/views/donatur_skema_view.dart index 5372011..82e5d52 100644 --- a/lib/app/modules/donatur/views/donatur_skema_view.dart +++ b/lib/app/modules/donatur/views/donatur_skema_view.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/modules/donatur/controllers/donatur_dashboard_controller.dart'; import 'package:penyaluran_app/app/widgets/section_header.dart'; diff --git a/lib/app/modules/donatur/views/donatur_view.dart b/lib/app/modules/donatur/views/donatur_view.dart index 682a918..c56ed91 100644 --- a/lib/app/modules/donatur/views/donatur_view.dart +++ b/lib/app/modules/donatur/views/donatur_view.dart @@ -6,6 +6,7 @@ import 'package:penyaluran_app/app/modules/donatur/views/donatur_skema_view.dart import 'package:penyaluran_app/app/modules/donatur/views/donatur_jadwal_view.dart'; import 'package:penyaluran_app/app/modules/donatur/views/donatur_laporan_view.dart'; import 'package:penyaluran_app/app/modules/donatur/views/donatur_penitipan_view.dart'; +import 'package:penyaluran_app/app/modules/donatur/views/donatur_riwayat_penitipan_view.dart'; import 'package:penyaluran_app/app/widgets/app_bottom_navigation_bar.dart'; import 'package:penyaluran_app/app/theme/app_theme.dart'; diff --git a/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart b/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart index 5e59518..d8fed51 100644 --- a/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart +++ b/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart @@ -891,13 +891,14 @@ class LaporanPenyaluranController extends GetxController { final stokBantuan = daftarPenerima .firstWhere((p) => p.stokBantuanId == stokId, orElse: () => PenerimaPenyaluranModel()) - ?.stokBantuan; + .stokBantuan; - if (stokBantuan == null) + if (stokBantuan == null) { return pw.TableRow(children: [ _buildPdfTableCell('-', ttf), _buildPdfTableCell('-', ttf), ]); + } final isUang = stokBantuan['is_uang'] == true; final formattedJumlah = isUang @@ -912,7 +913,7 @@ class LaporanPenyaluranController extends GetxController { align: pw.TextAlign.center), ], ); - }).toList(), + }), ], ), ], @@ -988,7 +989,7 @@ class LaporanPenyaluranController extends GetxController { align: pw.TextAlign.center), ], ); - }).toList(), + }), ], ), ], diff --git a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_create_view.dart b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_create_view.dart index 0074a33..b7d5c27 100644 --- a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_create_view.dart +++ b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_create_view.dart @@ -10,7 +10,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:file_picker/file_picker.dart'; class LaporanPenyaluranCreateView extends GetView { - const LaporanPenyaluranCreateView({Key? key}) : super(key: key); + const LaporanPenyaluranCreateView({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart index bd6b1b4..4695d35 100644 --- a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart +++ b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart @@ -11,7 +11,7 @@ import 'package:penyaluran_app/app/data/models/penerima_penyaluran_model.dart'; import 'package:url_launcher/url_launcher.dart'; class LaporanPenyaluranDetailView extends GetView { - const LaporanPenyaluranDetailView({Key? key}) : super(key: key); + const LaporanPenyaluranDetailView({super.key}); @override Widget build(BuildContext context) { @@ -385,8 +385,9 @@ class LaporanPenyaluranDetailView extends GetView { orElse: () => PenerimaPenyaluranModel()) .stokBantuan; - if (stokBantuan == null) + if (stokBantuan == null) { return const SizedBox.shrink(); + } final kategori = stokBantuan['kategori_bantuan'] != null @@ -939,9 +940,9 @@ class LaporanPenyaluranDetailView extends GetView { return InkWell( onTap: () async { - final Uri _url = Uri.parse(url); - if (await canLaunchUrl(_url)) { - await launchUrl(_url, mode: LaunchMode.externalApplication); + final Uri url0 = Uri.parse(url); + if (await canLaunchUrl(url0)) { + await launchUrl(url0, mode: LaunchMode.externalApplication); } else { Get.snackbar( 'Error', diff --git a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_edit_view.dart b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_edit_view.dart index 65796bb..2d7b696 100644 --- a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_edit_view.dart +++ b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_edit_view.dart @@ -8,7 +8,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:file_picker/file_picker.dart'; class LaporanPenyaluranEditView extends GetView { - const LaporanPenyaluranEditView({Key? key}) : super(key: key); + const LaporanPenyaluranEditView({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_view.dart b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_view.dart index d47f8bb..73c9206 100644 --- a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_view.dart +++ b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_view.dart @@ -10,7 +10,7 @@ import 'package:penyaluran_app/app/widgets/status_badge.dart'; import 'package:intl/intl.dart'; class LaporanPenyaluranView extends GetView { - const LaporanPenyaluranView({Key? key}) : super(key: key); + const LaporanPenyaluranView({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart b/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart index 26e9b34..38653e2 100644 --- a/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart @@ -39,35 +39,14 @@ class DetailPenyaluranController extends GetxController { if (penyaluran.value?.id != null) { loadPenyaluranDetails(penyaluran.value!.id!); } - checkUserRole(); } else if (penyaluranId != null) { // Jika hanya ID penyaluran yang diterima loadPenyaluranData(penyaluranId); - checkUserRole(); } else { isLoading.value = false; } } - Future checkUserRole() async { - try { - final user = _supabaseService.client.auth.currentUser; - if (user != null) { - final userData = await _supabaseService.client - .from('user_profile') - .select('role') - .eq('id', user.id) - .single(); - - if (userData['role'] == 'PETUGASDESA') { - isPetugasDesa.value = true; - } - } - } catch (e) { - print('Error checking user role: $e'); - } - } - Future loadPenyaluranData(String penyaluranId) async { try { isLoading.value = true; @@ -522,36 +501,33 @@ class DetailPenyaluranController extends GetxController { .eq('qr_code_hash', qrHash) .single(); - if (data != null) { - // Jika penerima ditemukan, konversi ke model - final Map sanitizedPenerimaData = - Map.from(data); + // Jika penerima ditemukan, konversi ke model + final Map sanitizedPenerimaData = + Map.from(data); - // Konversi jumlah_bantuan ke double jika bertipe String - if (sanitizedPenerimaData['jumlah_bantuan'] is String) { - sanitizedPenerimaData['jumlah_bantuan'] = double.tryParse( - sanitizedPenerimaData['jumlah_bantuan'] as String); - } - - // Konversi data ke model - final penerima = - PenerimaPenyaluranModel.fromJson(sanitizedPenerimaData); - - // Set isProcessing ke false sebelum navigasi untuk menghindari masalah loading - isProcessing.value = false; - - // Navigasi ke halaman konfirmasi dengan data terbaru - await Get.toNamed('/petugas-desa/konfirmasi-penerima/${penerima.id}', - arguments: { - 'penerima': penerima, - 'tanggal_penyaluran': penyaluran.value?.tanggalPenyaluran - }); - - // Refresh data - await refreshData(); - return true; + // Konversi jumlah_bantuan ke double jika bertipe String + if (sanitizedPenerimaData['jumlah_bantuan'] is String) { + sanitizedPenerimaData['jumlah_bantuan'] = + double.tryParse(sanitizedPenerimaData['jumlah_bantuan'] as String); } + // Konversi data ke model + final penerima = PenerimaPenyaluranModel.fromJson(sanitizedPenerimaData); + + // Set isProcessing ke false sebelum navigasi untuk menghindari masalah loading + isProcessing.value = false; + + // Navigasi ke halaman konfirmasi dengan data terbaru + await Get.toNamed('/petugas-desa/konfirmasi-penerima/${penerima.id}', + arguments: { + 'penerima': penerima, + 'tanggal_penyaluran': penyaluran.value?.tanggalPenyaluran + }); + + // Refresh data + await refreshData(); + return true; + return false; } catch (e) { print('Error verifikasi QR code: $e'); diff --git a/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart b/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart index 95a4d6d..dfaf1fd 100644 --- a/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart @@ -448,7 +448,7 @@ class JadwalPenyaluranController extends GetxController { .eq('id', stokBantuanId) .single(); - if (stokData != null && stokData['total_stok'] != null) { + if (stokData['total_stok'] != null) { final currentStok = stokData['total_stok'].toDouble(); final newStok = currentStok - totalStokDibutuhkan; diff --git a/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart b/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart index ebc21f7..92c18bc 100644 --- a/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart @@ -197,9 +197,63 @@ class PenitipanBantuanController extends GetxController { } Future pickfotoBuktiSerahTerima() async { + try { + // Tampilkan bottom sheet untuk memilih sumber foto + Get.bottomSheet( + Container( + padding: const EdgeInsets.all(16), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Pilih Sumber Foto', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 16), + ListTile( + leading: const Icon(Icons.camera_alt), + title: const Text('Kamera'), + onTap: () { + Get.back(); + _pickfotoBuktiSerahTerimaFrom(ImageSource.camera); + }, + ), + ListTile( + leading: const Icon(Icons.photo_library), + title: const Text('Galeri'), + onTap: () { + Get.back(); + _pickfotoBuktiSerahTerimaFrom(ImageSource.gallery); + }, + ), + ], + ), + ), + ); + } catch (e) { + print('Error showing bottom sheet: $e'); + Get.snackbar( + 'Error', + 'Terjadi kesalahan: ${e.toString()}', + snackPosition: SnackPosition.TOP, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + } + } + + // Fungsi helper untuk mengambil foto dari sumber yang dipilih + Future _pickfotoBuktiSerahTerimaFrom(ImageSource source) async { try { final pickedFile = await _imagePicker.pickImage( - source: ImageSource.camera, + source: source, imageQuality: 70, maxWidth: 1000, ); 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 813638a..576e762 100644 --- a/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart @@ -74,9 +74,7 @@ class PetugasDesaController extends GetxController { String get nama { // 1. Coba ambil dari AuthController displayName yang paling lengkap final authDisplayName = _authController.displayName; - if (authDisplayName != null && - authDisplayName != 'Pengguna' && - authDisplayName != user?.email) { + if (authDisplayName != 'Pengguna' && authDisplayName != user?.email) { return authDisplayName; } diff --git a/lib/app/modules/petugas_desa/views/dashboard_view.dart b/lib/app/modules/petugas_desa/views/dashboard_view.dart index ff7c3f4..cdd7e6c 100644 --- a/lib/app/modules/petugas_desa/views/dashboard_view.dart +++ b/lib/app/modules/petugas_desa/views/dashboard_view.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/routes/app_pages.dart'; import 'package:penyaluran_app/app/utils/date_time_helper.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; diff --git a/lib/app/modules/petugas_desa/views/detail_donatur_view.dart b/lib/app/modules/petugas_desa/views/detail_donatur_view.dart index 84e01b4..097f83b 100644 --- a/lib/app/modules/petugas_desa/views/detail_donatur_view.dart +++ b/lib/app/modules/petugas_desa/views/detail_donatur_view.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/controllers/donatur_controller.dart'; -import 'package:penyaluran_app/app/theme/app_theme.dart'; import 'package:penyaluran_app/app/data/models/donatur_model.dart'; import 'package:penyaluran_app/app/data/models/penitipan_bantuan_model.dart'; import 'package:penyaluran_app/app/widgets/dialogs/detail_penitipan_dialog.dart'; diff --git a/lib/app/modules/petugas_desa/views/detail_penerima_view.dart b/lib/app/modules/petugas_desa/views/detail_penerima_view.dart index f4c9351..eb8c909 100644 --- a/lib/app/modules/petugas_desa/views/detail_penerima_view.dart +++ b/lib/app/modules/petugas_desa/views/detail_penerima_view.dart @@ -2,7 +2,6 @@ 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'; -import 'package:intl/intl.dart'; import 'package:penyaluran_app/app/utils/date_time_helper.dart'; class DetailPenerimaView extends GetView { diff --git a/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart b/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart index fbb5c01..59e57f3 100644 --- a/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart +++ b/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart @@ -743,10 +743,10 @@ class _KonfirmasiPenerimaPageState extends State { // Hapus file sementara sebelum navigasi try { - if (signatureFile != null && signatureFile.existsSync()) { + if (signatureFile.existsSync()) { await signatureFile.delete(); } - if (tempDir != null && tempDir.existsSync()) { + if (tempDir.existsSync()) { await tempDir.delete(); } } catch (e) { diff --git a/lib/app/modules/petugas_desa/views/penitipan_view.dart b/lib/app/modules/petugas_desa/views/penitipan_view.dart index 4111ffc..1712fff 100644 --- a/lib/app/modules/petugas_desa/views/penitipan_view.dart +++ b/lib/app/modules/petugas_desa/views/penitipan_view.dart @@ -632,18 +632,26 @@ class PenitipanView extends GetView { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( - Icons.camera_alt, + Icons.add_photo_alternate, size: 48, color: Colors.grey.shade600, ), const SizedBox(height: 8), Text( - 'Ambil Foto', + 'Pilih Foto', style: TextStyle( color: Colors.grey.shade600, fontWeight: FontWeight.bold, ), ), + const SizedBox(height: 4), + Text( + 'Kamera atau Galeri', + style: TextStyle( + color: Colors.grey.shade600, + fontSize: 12, + ), + ), ], ), ), diff --git a/lib/app/modules/petugas_desa/views/stok_bantuan_view.dart b/lib/app/modules/petugas_desa/views/stok_bantuan_view.dart index 8eb33ec..15f8a84 100644 --- a/lib/app/modules/petugas_desa/views/stok_bantuan_view.dart +++ b/lib/app/modules/petugas_desa/views/stok_bantuan_view.dart @@ -426,7 +426,9 @@ class StokBantuanView extends GetView { context, icon: Icons.access_time, label: 'Terakhir Diperbarui', - value: DateTimeHelper.formatDateTime(item.updatedAt), + value: item.updatedAt != null + ? '${item.updatedAt!.day}/${item.updatedAt!.month}/${item.updatedAt!.year} ${item.updatedAt!.hour}:${item.updatedAt!.minute}' + : 'Tidak ada data', ), ), ], 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 320249c..f2c9d58 100644 --- a/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart +++ b/lib/app/modules/petugas_desa/views/tambah_penyaluran_view.dart @@ -90,29 +90,20 @@ class TambahPenyaluranView extends GetView { print('stokData $stokData'); - if (stokData != null) { - namaStokBantuan.value = - stokData['nama'] ?? 'Nama stok tidak tersedia'; - satuanStokBantuan.value = stokData['satuan'] ?? 'Tidak ada satuan'; - isUang.value = stokData['is_uang'] ?? false; + namaStokBantuan.value = stokData['nama'] ?? 'Nama stok tidak tersedia'; + satuanStokBantuan.value = stokData['satuan'] ?? 'Tidak ada satuan'; + isUang.value = stokData['is_uang'] ?? false; - // Ambil jumlah stok tersedia - if (stokData['total_stok'] != null) { - totalStokTersedia.value = stokData['total_stok'].toDouble(); - } else { - totalStokTersedia.value = 0; - } - - // Periksa kecukupan stok - isStokCukup.value = - totalStokTersedia.value >= totalStokDibutuhkan.value; + // Ambil jumlah stok tersedia + if (stokData['total_stok'] != null) { + totalStokTersedia.value = stokData['total_stok'].toDouble(); } else { - namaStokBantuan.value = 'Stok tidak ditemukan'; - satuanStokBantuan.value = ''; totalStokTersedia.value = 0; - isStokCukup.value = false; - isUang.value = false; } + + // Periksa kecukupan stok + isStokCukup.value = + totalStokTersedia.value >= totalStokDibutuhkan.value; } catch (e) { print('Error loading stok bantuan: $e'); namaStokBantuan.value = 'Error memuat data stok'; diff --git a/lib/app/modules/profile/controllers/profile_controller.dart b/lib/app/modules/profile/controllers/profile_controller.dart index 8d48151..53892f9 100644 --- a/lib/app/modules/profile/controllers/profile_controller.dart +++ b/lib/app/modules/profile/controllers/profile_controller.dart @@ -4,7 +4,6 @@ import 'package:penyaluran_app/app/data/models/user_model.dart'; import 'package:penyaluran_app/app/services/supabase_service.dart'; import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart'; import 'package:image_picker/image_picker.dart'; -import 'dart:io'; class ProfileController extends GetxController { final SupabaseService _supabaseService = Get.find(); diff --git a/lib/app/modules/profile/views/profile_view.dart b/lib/app/modules/profile/views/profile_view.dart index d1be05a..8091ffe 100644 --- a/lib/app/modules/profile/views/profile_view.dart +++ b/lib/app/modules/profile/views/profile_view.dart @@ -743,10 +743,10 @@ class ProfileView extends GetView { actions: [ TextButton( onPressed: () => Get.back(), - child: const Text('Batal'), style: TextButton.styleFrom( foregroundColor: Colors.grey[700], ), + child: const Text('Batal'), ), ElevatedButton( onPressed: () { diff --git a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart index a0049c8..3112fa2 100644 --- a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart +++ b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart @@ -125,7 +125,7 @@ class WargaDashboardController extends GetxController { print('DEBUG WARGA: Memuat data user dari AuthController'); print('DEBUG WARGA: baseUser: ${_authController.baseUser}'); print('DEBUG WARGA: roleData: ${_authController.roleData}'); - print('DEBUG WARGA: nama yang akan ditampilkan: ${nama}'); + print('DEBUG WARGA: nama yang akan ditampilkan: $nama'); print( 'DEBUG WARGA: displayName dari auth controller: ${_authController.displayName}'); diff --git a/lib/app/modules/warga/views/warga_dashboard_view.dart b/lib/app/modules/warga/views/warga_dashboard_view.dart index 061492c..b0b7cc6 100644 --- a/lib/app/modules/warga/views/warga_dashboard_view.dart +++ b/lib/app/modules/warga/views/warga_dashboard_view.dart @@ -539,7 +539,7 @@ class WargaDashboardView extends GetView { ), ], ); - }).toList(), + }), ], if (totalUang == 0 && totalNonUang.isEmpty) _buildSummaryItem( diff --git a/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart b/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart index 93d2701..035b7e7 100644 --- a/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart +++ b/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart @@ -4,7 +4,6 @@ import 'package:intl/intl.dart'; import 'package:penyaluran_app/app/data/models/penerima_penyaluran_model.dart'; import 'package:penyaluran_app/app/data/models/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:penyaluran_app/app/widgets/status_badge.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:image_picker/image_picker.dart'; diff --git a/lib/app/services/supabase_service.dart b/lib/app/services/supabase_service.dart index f51f102..8ac5dd2 100644 --- a/lib/app/services/supabase_service.dart +++ b/lib/app/services/supabase_service.dart @@ -265,18 +265,16 @@ class SupabaseService extends GetxService { } // Tambahkan data role-specific - if (roleData != null) { - combinedData['role_data'] = roleData; + combinedData['role_data'] = roleData; - // Tambahkan data desa jika ada - if (roleData['desa'] != null) { - combinedData['desa'] = roleData['desa']; - } + // Tambahkan data desa jika ada + if (roleData['desa'] != null) { + combinedData['desa'] = roleData['desa']; + } - // Tambahkan nama dari data role jika ada - if (roleData['nama_lengkap'] != null) { - combinedData['name'] = roleData['nama_lengkap']; - } + // Tambahkan nama dari data role jika ada + if (roleData['nama_lengkap'] != null) { + combinedData['name'] = roleData['nama_lengkap']; } // Cache profil untuk penggunaan berikutnya @@ -783,6 +781,8 @@ class SupabaseService extends GetxService { Future uploadFile( String filePath, String bucket, String folder) async { try { + print( + 'Uploading file from path: $filePath to bucket: $bucket in folder: $folder'); final fileName = filePath.split('/').last; final fileExt = fileName.split('.').last; final fileKey = @@ -1327,10 +1327,6 @@ class SupabaseService extends GetxService { .eq('role_name', 'warga') .single(); - if (roleResponse == null) { - throw 'Role warga tidak ditemukan'; - } - final roleId = roleResponse['id']; // Update role_id di auth.users @@ -1379,10 +1375,6 @@ class SupabaseService extends GetxService { .eq('role_name', 'donatur') .single(); - if (roleResponse == null) { - throw 'Role donatur tidak ditemukan'; - } - final roleId = roleResponse['id']; // Update role_id di auth.users @@ -1477,10 +1469,6 @@ class SupabaseService extends GetxService { .eq('role_name', 'petugas_desa') .single(); - if (roleResponse == null) { - throw 'Role petugas desa tidak ditemukan'; - } - final roleId = roleResponse['id']; // Update role_id di auth.users