From ba3e71efe7a2dd973f0460073419072d76ab413b Mon Sep 17 00:00:00 2001 From: Khafidh Fuadi Date: Sun, 30 Mar 2025 18:50:26 +0700 Subject: [PATCH] Perbarui model PenerimaPenyaluran untuk menyertakan properti qrCodeHash dan hapus properti yang tidak digunakan. Modifikasi controller DetailPenyaluranController untuk menambahkan fungsi pengambilan data penerima penyaluran berdasarkan ID. Sesuaikan tampilan di halaman konfirmasi penerima dan detail penerimaan untuk meningkatkan pengalaman pengguna. Hapus kode yang tidak diperlukan untuk menjaga kebersihan kode. --- .../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 +- .../arm64-v8a/configure_fingerprint.bin | 24 +- .../armeabi-v7a/configure_fingerprint.bin | 24 +- .../1o2r2b1v/x86/configure_fingerprint.bin | 24 +- .../1o2r2b1v/x86_64/configure_fingerprint.bin | 24 +- .../models/penerima_penyaluran_model.dart | 61 +- .../detail_penyaluran_controller.dart | 55 + .../pelaksanaan_penyaluran_controller.dart | 1 - .../views/detail_penyaluran_page.dart | 13 +- .../views/konfirmasi_penerima_page.dart | 1554 +++++++++++++---- .../views/warga_detail_penerimaan_view.dart | 28 - lib/app/routes/app_pages.dart | 13 +- lib/app/widgets/bantuan_card.dart | 26 - 16 files changed, 1416 insertions(+), 527 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 35d0246..9115535 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 a09f5bf..0f04b47 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 d341321..149cb05 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 51aff7d..8bdbdfb 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/android/app/.cxx/RelWithDebInfo/1o2r2b1v/arm64-v8a/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/arm64-v8a/configure_fingerprint.bin index 0a4c6c1..ad17a8f 100644 --- a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/arm64-v8a/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/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\RelWithDebInfo\1o2r2b1v\arm64-v8a\additional_project_files.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\additional_project_files.txt  2  2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\android_gradle_build.json  2 2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\android_gradle_build.json  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\android_gradle_build_mini.json  2 2y +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\android_gradle_build_mini.json  2 2y w -uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build.ninja  2 2} +uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build.ninja  2 2} { -yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build.ninja.txt  2 +yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build.ninja.txt  2  -~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build_file_index.txt  2 K 2 +~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\build_file_index.txt  2 K 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\compile_commands.json  2  +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\compile_commands.json  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\compile_commands.json.bin  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\metadata_generation_command.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\metadata_generation_command.txt  2  2 ~ -|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\prefab_config.json  2  ( 2 +|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\prefab_config.json  2  ( 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\symbol_folder_index.txt  2  x 2 \ No newline at end of file +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\arm64-v8a\symbol_folder_index.txt  2  x 2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/armeabi-v7a/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/armeabi-v7a/configure_fingerprint.bin index e73713c..d5afd90 100644 --- a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/armeabi-v7a/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/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\RelWithDebInfo\1o2r2b1v\armeabi-v7a\additional_project_files.txt  2  Т2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\additional_project_files.txt  2  Т2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\android_gradle_build.json  2 ڢ2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\android_gradle_build.json  2 ڢ2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\android_gradle_build_mini.json  2 2{ +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\android_gradle_build_mini.json  2 2{ y -wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build.ninja  2 2 +wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build.ninja  2 2 } -{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build.ninja.txt  2 +{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build.ninja.txt  2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build_file_index.txt  2 K 2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\build_file_index.txt  2 K 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\compile_commands.json  2  +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\compile_commands.json  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\compile_commands.json.bin  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\metadata_generation_command.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\metadata_generation_command.txt  2  2  -~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\prefab_config.json  2  ( 2 +~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\prefab_config.json  2  ( 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\symbol_folder_index.txt  2  z 2 \ No newline at end of file +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\armeabi-v7a\symbol_folder_index.txt  2  z 2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86/configure_fingerprint.bin index ee3e3c5..b3e736e 100644 --- a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/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  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\additional_project_files.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\additional_project_files.txt  2  2  -}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\android_gradle_build.json  2 2 +}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\android_gradle_build.json  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\android_gradle_build_mini.json  2 2s +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\android_gradle_build_mini.json  2 2s q -oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build.ninja  2 2w +oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build.ninja  2 2w u -sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build.ninja.txt  2| +sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build.ninja.txt  2| z -xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build_file_index.txt  2 K 2} +xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\build_file_index.txt  2 K 2} { -yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\compile_commands.json  2  +yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\compile_commands.json  2   -}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\compile_commands.json.bin  2 +}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\metadata_generation_command.txt  2  2z +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\metadata_generation_command.txt  2  2z x -vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\prefab_config.json  2  ( 2 +vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\prefab_config.json  2  ( 2 } -{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\symbol_folder_index.txt  2  r 2 \ No newline at end of file +{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86\symbol_folder_index.txt  2  r 2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86_64/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86_64/configure_fingerprint.bin index 424b783..6fd6255 100644 --- a/android/app/.cxx/RelWithDebInfo/1o2r2b1v/x86_64/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/1o2r2b1v/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  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\additional_project_files.txt  2  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\additional_project_files.txt  2  2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\android_gradle_build.json  2 2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\android_gradle_build.json  2 2  -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\android_gradle_build_mini.json  2 2v +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\android_gradle_build_mini.json  2 2v t -rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build.ninja  2 2z +rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build.ninja  2 2z x -vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build.ninja.txt  2 +vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build.ninja.txt  2 } -{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build_file_index.txt  2 K 2 +{D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\build_file_index.txt  2 K 2 ~ -|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\compile_commands.json  2  +|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\compile_commands.json  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\compile_commands.json.bin  2 +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\compile_commands.json.bin  2   -D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\metadata_generation_command.txt  2  2} +D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\metadata_generation_command.txt  2  2} { -yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\prefab_config.json  2  ( 2 +yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\prefab_config.json  2  ( 2  -~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\symbol_folder_index.txt  2  u 2 \ No newline at end of file +~D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\RelWithDebInfo\1o2r2b1v\x86_64\symbol_folder_index.txt  2  u 2 \ No newline at end of file diff --git a/lib/app/data/models/penerima_penyaluran_model.dart b/lib/app/data/models/penerima_penyaluran_model.dart index 6531f2c..3c9413d 100644 --- a/lib/app/data/models/penerima_penyaluran_model.dart +++ b/lib/app/data/models/penerima_penyaluran_model.dart @@ -8,22 +8,25 @@ class PenerimaPenyaluranModel { final String? statusPenerimaan; final DateTime? tanggalPenerimaan; final String? buktiPenerimaan; - final String? keterangan; final double? jumlahBantuan; final String? stokBantuanId; - final Map? warga; // Data warga yang terkait final String? tandaTangan; - final bool? isUang; // Apakah bantuan berupa uang - final String? satuan; // Satuan bantuan + final String? qrCodeHash; + + // Relasi data + final Map? warga; // Data warga yang terkait final Map? stokBantuan; // Data stok bantuan final Map? penyaluranBantuan; // Data penyaluran bantuan - final String? kategoriNama; // Nama kategori bantuan - final String? namaPenyaluran; // Nama penyaluran - final String? deskripsiPenyaluran; // Deskripsi penyaluran - final String? lokasiPenyaluranNama; // Nama lokasi penyaluran - final String? lokasiPenyaluranAlamat; // Alamat lokasi penyaluran - final String? qrCodeHash; // Hash untuk QR code - final String? statusPenyaluran; // Status penyaluran + + // Properti turunan yang diambil dari relasi + final String? kategoriNama; // Nama kategori bantuan dari relasi + final String? namaPenyaluran; // Nama penyaluran dari relasi + final String? deskripsiPenyaluran; // Deskripsi penyaluran dari relasi + final String? lokasiPenyaluranNama; // Nama lokasi penyaluran dari relasi + final String? lokasiPenyaluranAlamat; // Alamat lokasi penyaluran dari relasi + final String? statusPenyaluran; // Status penyaluran dari relasi + final String? satuan; // Satuan dari relasi stok bantuan + final bool? isUang; // Flag is_uang dari relasi stok bantuan PenerimaPenyaluranModel({ this.id, @@ -33,22 +36,23 @@ class PenerimaPenyaluranModel { this.statusPenerimaan, this.tanggalPenerimaan, this.buktiPenerimaan, - this.keterangan, this.jumlahBantuan, this.stokBantuanId, - this.warga, this.tandaTangan, - this.isUang, - this.satuan, + this.qrCodeHash, + // Relasi + this.warga, this.stokBantuan, this.penyaluranBantuan, + // Properti turunan this.kategoriNama, this.namaPenyaluran, this.deskripsiPenyaluran, this.lokasiPenyaluranNama, this.lokasiPenyaluranAlamat, - this.qrCodeHash, this.statusPenyaluran, + this.satuan, + this.isUang, }); factory PenerimaPenyaluranModel.fromRawJson(String str) => @@ -69,22 +73,23 @@ class PenerimaPenyaluranModel { ? DateTime.parse(json["tanggal_penerimaan"]) : null, buktiPenerimaan: json["bukti_penerimaan"], - keterangan: json["keterangan"], jumlahBantuan: json["jumlah_bantuan"]?.toDouble(), stokBantuanId: json["stok_bantuan_id"], - warga: json["warga"], tandaTangan: json["tanda_tangan"], - isUang: json["is_uang"], - satuan: json["satuan"], + qrCodeHash: json["qr_code_hash"], + // Relasi + warga: json["warga"], stokBantuan: json["stok_bantuan"], penyaluranBantuan: json["penyaluran_bantuan"], + // Properti turunan kategoriNama: json["kategori_nama"], namaPenyaluran: json["nama_penyaluran"], deskripsiPenyaluran: json["deskripsi_penyaluran"], lokasiPenyaluranNama: json["lokasi_penyaluran_nama"], lokasiPenyaluranAlamat: json["lokasi_penyaluran_alamat"], - qrCodeHash: json["qr_code_hash"], statusPenyaluran: json["status_penyaluran"], + satuan: json["satuan"] ?? json["stok_bantuan"]?["satuan"], + isUang: json["is_uang"] ?? json["stok_bantuan"]?["is_uang"], ); Map toJson() => { @@ -95,21 +100,11 @@ class PenerimaPenyaluranModel { "status_penerimaan": statusPenerimaan, "tanggal_penerimaan": tanggalPenerimaan?.toIso8601String(), "bukti_penerimaan": buktiPenerimaan, - "keterangan": keterangan, "jumlah_bantuan": jumlahBantuan, "stok_bantuan_id": stokBantuanId, - "warga": warga, "tanda_tangan": tandaTangan, - "is_uang": isUang, - "satuan": satuan, - "stok_bantuan": stokBantuan, - "penyaluran_bantuan": penyaluranBantuan, - "kategori_nama": kategoriNama, - "nama_penyaluran": namaPenyaluran, - "deskripsi_penyaluran": deskripsiPenyaluran, - "lokasi_penyaluran_nama": lokasiPenyaluranNama, - "lokasi_penyaluran_alamat": lokasiPenyaluranAlamat, "qr_code_hash": qrCodeHash, - "status_penyaluran": statusPenyaluran, + // Relasi tidak perlu disertakan dalam toJson karena + // biasanya hanya digunakan untuk serialisasi ke database }; } 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 f50ef4b..613ed9e 100644 --- a/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart @@ -604,4 +604,59 @@ class DetailPenyaluranController extends GetxController { isExporting.value = false; } } + + // Fungsi untuk mengambil data penerima penyaluran berdasarkan ID + Future getPenerimaPenyaluranById( + String penerimaPenyaluranId) async { + try { + // Ambil data penerima penyaluran dengan relasinya + final data = await _supabaseService.client + .from('penerima_penyaluran') + .select( + '*, warga:warga_id(*), stok_bantuan:stok_bantuan_id(*), penyaluran_bantuan:penyaluran_bantuan_id(*)') + .eq('id', penerimaPenyaluranId) + .single(); + + // Konversi data ke model + final Map sanitizedData = + Map.from(data); + + // Konversi jumlah_bantuan ke double jika bertipe String + if (sanitizedData['jumlah_bantuan'] is String) { + sanitizedData['jumlah_bantuan'] = + double.tryParse(sanitizedData['jumlah_bantuan'] as String); + } + + return PenerimaPenyaluranModel.fromJson(sanitizedData); + } catch (e) { + print('Error mengambil data penerima penyaluran: $e'); + Get.snackbar( + 'Error', + 'Terjadi kesalahan saat mengambil data penerima', + backgroundColor: Colors.red, + colorText: Colors.white, + ); + return null; + } + } + + // Fungsi untuk memuat penyaluran dengan id tertentu + Future getDetailPenyaluran(String penyaluranId) async { + try { + isLoading.value = true; + + // Ambil data penyaluran + await loadPenyaluranData(penyaluranId); + } catch (e) { + print('Error getDetailPenyaluran: $e'); + Get.snackbar( + 'Error', + 'Gagal memuat data detail penyaluran', + backgroundColor: Colors.red, + colorText: Colors.white, + ); + } finally { + isLoading.value = false; + } + } } diff --git a/lib/app/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart b/lib/app/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart index ddb33a8..4c7f330 100644 --- a/lib/app/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart +++ b/lib/app/modules/petugas_desa/controllers/pelaksanaan_penyaluran_controller.dart @@ -376,7 +376,6 @@ class PelaksanaanPenyaluranController extends GetxController { statusPenerimaan: 'DITERIMA', tanggalPenerimaan: penerimaPenyaluran[index].tanggalPenerimaan, buktiPenerimaan: penerimaPenyaluran[index].buktiPenerimaan, - keterangan: penerimaPenyaluran[index].keterangan, jumlahBantuan: penerimaPenyaluran[index].jumlahBantuan, stokBantuanId: penerimaPenyaluran[index].stokBantuanId, warga: penerimaPenyaluran[index].warga, diff --git a/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart b/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart index 4db0fcd..74c3bb9 100644 --- a/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart +++ b/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart @@ -1406,16 +1406,10 @@ class DetailPenyaluranPage extends StatelessWidget { void _showKonfirmasiPenerimaan( BuildContext context, PenerimaPenyaluranModel penerima) { - // Dapatkan data jumlah bantuan dari penerima - final jumlahBantuan = penerima.jumlahBantuan?.toString() ?? '5'; - - // Navigasi ke halaman konfirmasi penerima + // Navigasi ke halaman konfirmasi penerima dengan hanya mengirimkan ID Get.to( () => KonfirmasiPenerimaPage( - penerima: penerima, - bentukBantuan: - null, // Tidak ada data bentuk bantuan yang tersedia langsung - jumlahBantuan: jumlahBantuan, + penerimaPenyaluranId: penerima.id!, tanggalPenyaluran: controller.penyaluran.value?.tanggalPenyaluran, ), )?.then((result) { @@ -1778,9 +1772,6 @@ class DetailPenyaluranPage extends StatelessWidget { if (penerima.jumlahBantuan != null) _buildInfoRow('Jumlah Bantuan', penerima.jumlahBantuan.toString()), - if (penerima.keterangan != null && - penerima.keterangan!.isNotEmpty) - _buildInfoRow('Keterangan', penerima.keterangan!), ], ), ), 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 755d55d..3d86bae 100644 --- a/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart +++ b/lib/app/modules/petugas_desa/views/konfirmasi_penerima_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:penyaluran_app/app/data/models/penerima_penyaluran_model.dart'; -import 'package:penyaluran_app/app/data/models/bentuk_bantuan_model.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart'; import 'package:penyaluran_app/app/theme/app_theme.dart'; import 'package:image_picker/image_picker.dart'; @@ -11,16 +10,12 @@ import 'dart:typed_data'; import 'package:penyaluran_app/app/utils/format_helper.dart'; class KonfirmasiPenerimaPage extends StatefulWidget { - final PenerimaPenyaluranModel penerima; - final BentukBantuanModel? bentukBantuan; - final String? jumlahBantuan; + final String penerimaPenyaluranId; final DateTime? tanggalPenyaluran; const KonfirmasiPenerimaPage({ super.key, - required this.penerima, - this.bentukBantuan, - this.jumlahBantuan, + required this.penerimaPenyaluranId, this.tanggalPenyaluran, }); @@ -29,13 +24,14 @@ class KonfirmasiPenerimaPage extends StatefulWidget { } class _KonfirmasiPenerimaPageState extends State { - late PenerimaPenyaluranModel penerima; + PenerimaPenyaluranModel? penerima; final controller = Get.find(); final ImagePicker _picker = ImagePicker(); File? _buktiPenerimaan; bool _setujuPenerimaan = false; bool _setujuPenggunaan = false; bool _isLoading = false; + bool _isDataLoading = true; // Loading state untuk data // Controller untuk tanda tangan final SignatureController _signatureController = SignatureController( @@ -50,11 +46,44 @@ class _KonfirmasiPenerimaPageState extends State { @override void initState() { super.initState(); - // Menggunakan data penerima yang diberikan dari arguments - penerima = widget.penerima; - print('KonfirmasiPenerimaPage - ID Penerima: ${penerima.id}'); - print( - 'KonfirmasiPenerimaPage - Nama Penerima: ${penerima.warga?['nama_lengkap']}'); + // Mengambil data penerima berdasarkan ID + _loadPenerimaPenyaluranData(); + } + + // Fungsi untuk mengambil data penerima dari database + Future _loadPenerimaPenyaluranData() async { + setState(() { + _isDataLoading = true; + }); + + try { + // Ambil data penerima beserta relasinya menggunakan ID + penerima = await controller + .getPenerimaPenyaluranById(widget.penerimaPenyaluranId); + + if (penerima != null) { + print('KonfirmasiPenerimaPage - ID Penerima: ${penerima!.id}'); + print( + 'KonfirmasiPenerimaPage - Nama Penerima: ${penerima!.warga?['nama_lengkap']}'); + + // Jika penerima memiliki penyaluran_bantuan_id, ambil detail penyaluran + if (penerima!.penyaluranBantuanId != null) { + await controller.getDetailPenyaluran(penerima!.penyaluranBantuanId!); + } + } + } catch (e) { + print('Error saat mengambil data penerima: $e'); + Get.snackbar( + 'Error', + 'Gagal memuat data penerima, silakan coba lagi', + backgroundColor: Colors.red, + colorText: Colors.white, + ); + } finally { + setState(() { + _isDataLoading = false; + }); + } } @override @@ -66,46 +95,109 @@ class _KonfirmasiPenerimaPageState extends State { @override Widget build(BuildContext context) { - final warga = penerima.warga; + // Jika data masih loading atau penerima null, tampilkan loading indicator + if (_isDataLoading || penerima == null) { + return Scaffold( + appBar: AppBar( + title: const Text('Konfirmasi Penerimaan'), + centerTitle: true, + elevation: 0, + backgroundColor: AppTheme.primaryColor, + foregroundColor: Colors.white, + ), + body: const Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator(color: AppTheme.primaryColor), + SizedBox(height: 16), + Text( + 'Memuat data penerimaan...', + style: TextStyle( + fontWeight: FontWeight.w500, + color: AppTheme.primaryColor, + ), + ), + ], + ), + ), + ); + } + + final warga = penerima!.warga; return Scaffold( appBar: AppBar( - title: const Text('Form Konfirmasi Penerimaan Bantuan'), + title: const Text('Konfirmasi Penerimaan'), centerTitle: true, + elevation: 0, + backgroundColor: AppTheme.primaryColor, + foregroundColor: Colors.white, leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Get.back(), ), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(16), + ), + ), ), body: _isLoading ? const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - CircularProgressIndicator(), + CircularProgressIndicator(color: AppTheme.primaryColor), SizedBox(height: 16), - Text('Sedang memproses konfirmasi...'), + Text( + 'Sedang memproses konfirmasi...', + style: TextStyle( + fontWeight: FontWeight.w500, + color: AppTheme.primaryColor, + ), + ), ], ), ) - : SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildDetailPenerimaSection(warga), - const SizedBox(height: 16), - _buildDetailBantuanSection(), - const SizedBox(height: 16), - _buildFotoBuktiSection(), - const SizedBox(height: 16), - _buildTandaTanganSection(), - const SizedBox(height: 16), - _buildFormPersetujuanSection(), - const SizedBox(height: 24), - _buildKonfirmasiButton(), - ], + : Container( + color: Colors.grey[50], + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Form Konfirmasi Penerimaan Bantuan', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, + ), + ), + const SizedBox(height: 4), + Text( + 'Silahkan isi data-data berikut untuk mengkonfirmasi penerimaan bantuan', + style: TextStyle( + fontSize: 14, + color: Colors.grey[600], + ), + ), + const SizedBox(height: 24), + _buildDetailPenerimaSection(warga), + const SizedBox(height: 16), + _buildDetailBantuanSection(), + const SizedBox(height: 16), + _buildFotoBuktiSection(), + const SizedBox(height: 16), + _buildTandaTanganSection(), + const SizedBox(height: 16), + _buildFormPersetujuanSection(), + const SizedBox(height: 24), + _buildKonfirmasiButton(), + ], + ), ), ), ), @@ -123,151 +215,343 @@ class _KonfirmasiPenerimaPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Detail Penerima', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppTheme.primaryColor, - ), - ), - const SizedBox(height: 16), - - // Foto Identitas Row( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Foto Identitas', - style: TextStyle( - fontWeight: FontWeight.w500, + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppTheme.primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + Icons.person_outline, + color: AppTheme.primaryColor, ), ), - const Spacer(), - Container( - width: 60, - height: 80, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(8), - image: warga?['foto_identitas'] != null - ? DecorationImage( - image: NetworkImage(warga!['foto_identitas']), - fit: BoxFit.cover, - ) - : null, + const SizedBox(width: 12), + const Text( + 'Detail Penerima', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, ), - child: warga?['foto_identitas'] == null - ? const Icon(Icons.person, color: Colors.grey) - : null, ), ], ), + const SizedBox(height: 16), const Divider(), - //nama lengkap - _buildInfoRow('Nama Lengkap', warga?['nama_lengkap'] ?? 'Bajiyadi'), - - // NIK - _buildInfoRow('NIK', warga?['nik'] ?? '3201020107030010'), + // Foto & Identitas Utama + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Foto identitas + Container( + width: 80, + height: 100, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey[300]!), + image: warga?['foto_profil'] != null + ? DecorationImage( + image: NetworkImage(warga!['foto_profil']), + fit: BoxFit.cover, + ) + : null, + ), + child: warga?['foto_profil'] == null + ? Icon(Icons.person, color: Colors.grey[400], size: 40) + : null, + ), + const SizedBox(width: 16), + // Informasi identitas utama + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + warga?['nama_lengkap'] ?? 'Bajiyadi', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + ), + const SizedBox(height: 4), + _buildKeyValueText( + 'NIK', warga?['nik'] ?? '3201020107030010'), + const SizedBox(height: 4), + _buildKeyValueText( + 'No KK', warga?['no_kk'] ?? '3201020107030393'), + const SizedBox(height: 4), + _buildKeyValueText( + 'Telepon', warga?['no_telepon'] ?? '089891256532'), + ], + ), + ), + ], + ), + ), const Divider(), - // No KK - _buildInfoRow('No KK', warga?['no_kk'] ?? '3201020107030393'), - const Divider(), + // Informasi Personal + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: Colors.blue[50], + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Informasi Personal', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.blue, + ), + ), + const SizedBox(height: 8), + Row( + children: [ + Expanded( + child: _buildInfoItem( + icon: Icons.wc_outlined, + title: 'Jenis Kelamin', + value: warga?['jenis_kelamin'] ?? 'Pria', + ), + ), + Expanded( + child: _buildInfoItem( + icon: Icons.bookmark_outlined, + title: 'Agama', + value: warga?['agama'] ?? 'Islam', + ), + ), + ], + ), + const SizedBox(height: 8), + _buildInfoItem( + icon: Icons.cake_outlined, + title: 'Tempat, Tanggal Lahir', + value: warga?['tempat_lahir'] != null && + warga?['tanggal_lahir'] != null + ? '${warga!['tempat_lahir']}, ${FormatHelper.formatDateTime(DateTime.parse(warga['tanggal_lahir']), format: 'd MMMM yyyy')}' + : 'Bogor, 2 Juni 1990', + ), + ], + ), + ), + const SizedBox(height: 12), - // No Handphone - _buildInfoRow( - 'No Handphone', warga?['no_telepon'] ?? '089891256532'), - const Divider(), + // Alamat + _buildDetailItem( + icon: Icons.home_outlined, + title: 'Alamat', + value: warga?['alamat'] ?? + 'Jl. Letda Natsir No. 22 RT 001/003\nKec. Gunung Putri Kab. Bogor', + color: Colors.green, + ), + + const SizedBox(height: 12), + + // Pekerjaan & Pendidikan + _buildDetailItem( + icon: Icons.work_outline, + title: 'Pekerjaan', + value: warga?['pekerjaan'] ?? 'Petani', + color: Colors.orange, + ), + const SizedBox(height: 12), + _buildDetailItem( + icon: Icons.school_outlined, + title: 'Pendidikan', + value: warga?['pendidikan_terakhir'] ?? 'Sekolah Dasar (SD)', + color: Colors.purple, + ), + const SizedBox(height: 12), // Email - _buildInfoRow('Email', warga?['email'] ?? 'bajiyadi@gmail.com'), - const Divider(), - - // Jenis Kelamin - _buildInfoRow('Jenis Kelamin', warga?['jenis_kelamin'] ?? 'Pria'), - const Divider(), - - // Agama - _buildInfoRow('Agama', warga?['agama'] ?? 'Islam'), - const Divider(), - - // Tempat, Tanggal Lahir - _buildInfoRow( - 'Tempat, Tanggal Lahir', - warga?['tempat_lahir'] != null && - warga?['tanggal_lahir'] != null - ? '${warga!['tempat_lahir']}, ${FormatHelper.formatDateTime(DateTime.parse(warga['tanggal_lahir']), format: 'd MMMM yyyy')}' - : 'Bogor, 2 Juni 1990'), - const Divider(), - - // Alamat Lengkap - _buildInfoRow( - 'Alamat Lengkap', - warga?['alamat'] ?? - 'Jl. Letda Natsir No. 22 RT 001/003\nKec. Gunung Putri Kab. Bogor'), - const Divider(), - - // Pekerjaan - _buildInfoRow('Pekerjaan', warga?['pekerjaan'] ?? 'Petani'), - const Divider(), - - // Pendidikan Terakhir - _buildInfoRow('Pendidikan Terakhir', - warga?['pendidikan_terakhir'] ?? 'Sekolah Dasar (SD)'), + _buildDetailItem( + icon: Icons.email_outlined, + title: 'Email', + value: warga?['email'] ?? 'bajiyadi@gmail.com', + color: Colors.red, + ), ], ), ), ); } + Widget _buildKeyValueText(String key, String value) { + return Row( + children: [ + Text( + '$key: ', + style: TextStyle( + fontSize: 13, + color: Colors.grey[600], + ), + ), + Expanded( + child: Text( + value, + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + ), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ); + } + + Widget _buildInfoItem({ + required IconData icon, + required String title, + required String value, + }) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(icon, size: 16, color: Colors.blue[700]), + const SizedBox(width: 4), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 12, + color: Colors.grey[600], + ), + ), + Text( + value, + style: const TextStyle( + fontSize: 13, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + ], + ); + } + + Widget _buildDetailItem({ + required IconData icon, + required String title, + required String value, + required Color color, + }) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(icon, size: 20, color: color), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontWeight: FontWeight.bold, + color: color, + fontSize: 13, + ), + ), + const SizedBox(height: 2), + Text( + value, + style: const TextStyle( + fontSize: 13, + ), + ), + ], + ), + ), + ], + ), + ); + } + Widget _buildDetailBantuanSection() { - // Tentukan satuan berdasarkan data yang tersedia + // Tentukan satuan dan apakah bantuan berupa uang String satuan = ''; - if (widget.bentukBantuan?.satuan != null) { - satuan = widget.bentukBantuan!.satuan!; - } else if (penerima.satuan != null) { - satuan = penerima.satuan!; + bool isUang = false; + + // Ambil dari stok_bantuan jika tersedia (prioritas utama) + if (penerima!.stokBantuan != null && + penerima!.stokBantuan!['satuan'] != null) { + satuan = penerima!.stokBantuan!['satuan']; + // Cek apakah bantuan berupa uang dari stok_bantuan + isUang = penerima!.stokBantuan!['is_uang'] ?? false; + } else if (penerima!.satuan != null) { + // Ambil dari property satuan di model (sudah diambil dari relasi dalam fromJson) + satuan = penerima!.satuan!; + isUang = penerima!.isUang ?? false; } else { - // Default satuan jika tidak ada - satuan = 'Kg'; + // Default jika tidak ada informasi satuan + satuan = 'buah'; + isUang = false; } + // Tentukan tanggal dan waktu penyaluran String tanggalWaktuPenyaluran = ''; if (widget.tanggalPenyaluran != null) { final tanggal = FormatHelper.formatDateTime(widget.tanggalPenyaluran!); - final waktuMulai = FormatHelper.formatTime(widget.tanggalPenyaluran!); - final waktuSelesai = FormatHelper.formatTime( - widget.tanggalPenyaluran!.add(const Duration(hours: 1))); - tanggalWaktuPenyaluran = '$tanggal $waktuMulai-$waktuSelesai'; - } else if (penerima.penyaluranBantuan != null && - penerima.penyaluranBantuan!['tanggal_penyaluran'] != null) { + tanggalWaktuPenyaluran = tanggal; + } else if (penerima!.penyaluranBantuan != null && + penerima!.penyaluranBantuan!['tanggal_penyaluran'] != null) { final tanggalPenyaluran = - DateTime.parse(penerima.penyaluranBantuan!['tanggal_penyaluran']); + DateTime.parse(penerima!.penyaluranBantuan!['tanggal_penyaluran']); + final tanggal = FormatHelper.formatDateTime(tanggalPenyaluran); - final waktuMulai = FormatHelper.formatTime(tanggalPenyaluran); - final waktuSelesai = FormatHelper.formatTime( - tanggalPenyaluran.add(const Duration(hours: 1))); - tanggalWaktuPenyaluran = '$tanggal $waktuMulai-$waktuSelesai'; + + tanggalWaktuPenyaluran = tanggal; } else { - tanggalWaktuPenyaluran = '09 April 2025 13:00-14:00'; + tanggalWaktuPenyaluran = 'Belum terjadwal'; } // Ambil nama bantuan dari model jika tersedia - String namaBantuan = 'Beras'; - if (widget.bentukBantuan?.nama != null) { - namaBantuan = widget.bentukBantuan!.nama!; - } else if (penerima.kategoriNama != null) { - namaBantuan = penerima.kategoriNama!; + String namaBantuan = ''; + if (penerima!.stokBantuan != null && + penerima!.stokBantuan!['nama'] != null) { + // Ambil dari stok_bantuan (prioritas utama) + namaBantuan = penerima!.stokBantuan!['nama']; + } else if (penerima!.kategoriNama != null && + penerima!.kategoriNama!.isNotEmpty) { + namaBantuan = penerima!.kategoriNama!; + } else if (penerima!.penyaluranBantuan?['kategori']?['nama'] != null) { + namaBantuan = penerima!.penyaluranBantuan!['kategori']['nama']; + } else { + namaBantuan = ''; } - // Ambil jumlah bantuan - String jumlahBantuan = '5'; - if (widget.jumlahBantuan != null) { - jumlahBantuan = widget.jumlahBantuan!; - } else if (penerima.jumlahBantuan != null) { - jumlahBantuan = penerima.jumlahBantuan.toString(); + // Ambil jumlah bantuan dari property jumlahBantuan di model + String jumlahBantuan = ''; + if (penerima!.jumlahBantuan != null) { + jumlahBantuan = penerima!.jumlahBantuan.toString(); + } else if (penerima!.penyaluranBantuan?['jumlah'] != null) { + jumlahBantuan = penerima!.penyaluranBantuan!['jumlah'].toString(); + } else { + jumlahBantuan = '1'; } return Card( @@ -280,26 +564,220 @@ class _KonfirmasiPenerimaPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Detail Bantuan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppTheme.primaryColor, - ), + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.green.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + isUang + ? Icons.payments_outlined + : Icons.inventory_2_outlined, + color: Colors.green, + ), + ), + const SizedBox(width: 12), + const Text( + 'Informasi Penerimaan', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, + ), + ), + ], ), const SizedBox(height: 16), - - // Bentuk Bantuan - _buildInfoRow('Bentuk Bantuan', namaBantuan), const Divider(), - // Nilai Bantuan - _buildInfoRow('Nilai Bantuan', '$jumlahBantuan$satuan'), - const Divider(), + // Informasi Bantuan dalam Card berwarna + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Colors.blue[50]!, + Colors.blue[100]!, + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 6, + offset: const Offset(0, 3), + ), + ], + ), + child: Column( + children: [ + // Bentuk Bantuan + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(6), + ), + child: Icon( + isUang + ? Icons.account_balance_wallet_outlined + : Icons.category_outlined, + color: Colors.indigo, + size: 20, + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + isUang ? 'Jenis Bantuan Uang' : 'Jenis Bantuan', + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), + ), + Text( + namaBantuan, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.indigo, + ), + ), + ], + ), + ), + ], + ), - // Tanggal Penyaluran - _buildInfoRow('Tanggal Penyaluran', tanggalWaktuPenyaluran), + const SizedBox(height: 12), + const Divider(height: 1, color: Colors.white), + const SizedBox(height: 12), + + // Nilai Bantuan + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(6), + ), + child: Icon( + isUang ? Icons.attach_money : Icons.scale_outlined, + color: Colors.green, + size: 20, + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + isUang ? 'Nilai Bantuan' : 'Jumlah Bantuan', + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), + ), + Row( + children: [ + if (isUang) + Text( + 'Rp ${FormatHelper.formatNumber(double.tryParse(jumlahBantuan) ?? 0)}', + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ) + else + Text( + jumlahBantuan, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ), + if (!isUang) ...[ + const SizedBox(width: 4), + Text( + satuan, + style: TextStyle( + fontSize: 14, + color: Colors.grey[600], + ), + ), + ], + ], + ), + ], + ), + ), + ], + ), + + const SizedBox(height: 12), + const Divider(height: 1, color: Colors.white), + const SizedBox(height: 12), + + // Tanggal Penyaluran + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(6), + ), + child: const Icon( + Icons.event_outlined, + color: Colors.orange, + size: 20, + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Tanggal & Waktu Penyaluran', + style: TextStyle( + fontSize: 12, + color: Colors.grey, + ), + ), + Text( + tanggalWaktuPenyaluran, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.orange, + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), ], ), ), @@ -317,47 +795,163 @@ class _KonfirmasiPenerimaPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Foto Bukti Penerimaan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppTheme.primaryColor, + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.purple.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + Icons.camera_alt_outlined, + color: Colors.purple, + ), + ), + const SizedBox(width: 12), + const Text( + 'Foto Bukti Penerimaan', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, + ), + ), + ], + ), + const SizedBox(height: 16), + + // Deskripsi Singkat + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.blue[50], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.blue[100]!), + ), + child: Row( + children: [ + Icon(Icons.info_outline, size: 20, color: Colors.blue[700]), + const SizedBox(width: 8), + Expanded( + child: Text( + 'Ambil foto penerima bersama bantuan yang diberikan sebagai bukti penerimaan', + style: TextStyle( + color: Colors.blue[800], + fontSize: 13, + ), + ), + ), + ], ), ), const SizedBox(height: 16), + + // Area Foto GestureDetector( onTap: _ambilFoto, child: Container( width: double.infinity, - height: 120, + height: 180, decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.grey[300]!), + border: Border.all( + color: _buktiPenerimaan != null + ? Colors.transparent + : Colors.grey[300]!, + width: 1, + ), + boxShadow: _buktiPenerimaan != null + ? [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 8, + offset: const Offset(0, 3), + ), + ] + : null, ), child: _buktiPenerimaan != null - ? ClipRRect( - borderRadius: BorderRadius.circular(12), - child: Image.file( - _buktiPenerimaan!, - fit: BoxFit.cover, - ), + ? Stack( + children: [ + // Foto yang dipilih + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.file( + _buktiPenerimaan!, + fit: BoxFit.cover, + width: double.infinity, + height: 180, + ), + ), + + // Tombol ganti foto + Positioned( + bottom: 8, + right: 8, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.6), + borderRadius: BorderRadius.circular(20), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.edit, + color: Colors.white, + size: 16, + ), + const SizedBox(width: 4), + const Text( + 'Ubah Foto', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], ) : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.add_photo_alternate_outlined, - size: 40, - color: Colors.grey[600], + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.purple.withOpacity(0.1), + shape: BoxShape.circle, + ), + child: Icon( + Icons.camera_alt, + size: 40, + color: Colors.purple[700], + ), ), - const SizedBox(height: 8), + const SizedBox(height: 16), Text( - 'Tambah Foto', + 'Tambah Foto Bukti', + style: TextStyle( + color: Colors.grey[800], + fontWeight: FontWeight.w500, + fontSize: 15, + ), + ), + const SizedBox(height: 4), + Text( + 'Ketuk untuk mengambil foto', style: TextStyle( color: Colors.grey[600], - fontWeight: FontWeight.w500, + fontSize: 13, ), ), ], @@ -381,71 +975,181 @@ class _KonfirmasiPenerimaPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Tanda Tangan Digital Penerima', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppTheme.primaryColor, + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.blue.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + Icons.draw_outlined, + color: Colors.blue, + ), + ), + const SizedBox(width: 12), + const Text( + 'Tanda Tangan Digital', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, + ), + ), + ], + ), + const SizedBox(height: 16), + + // Deskripsi Tanda Tangan + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.amber[50], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.amber[100]!), + ), + child: Row( + children: [ + Icon(Icons.info_outline, size: 20, color: Colors.amber[700]), + const SizedBox(width: 8), + Expanded( + child: Text( + 'Bubuhkan tanda tangan penerima bantuan di area yang disediakan', + style: TextStyle( + color: Colors.amber[900], + fontSize: 13, + ), + ), + ), + ], ), ), const SizedBox(height: 16), - // Area tanda tangan - Container( - width: double.infinity, - height: 200, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.grey[300]!), - ), - child: _signatureImage != null - ? ClipRRect( - borderRadius: BorderRadius.circular(12), - child: Image.memory( - _signatureImage!, - fit: BoxFit.contain, - ), - ) - : Signature( - controller: _signatureController, - backgroundColor: Colors.white, - height: 200, - width: double.infinity, + // Area tanda tangan dengan badge status + Stack( + children: [ + // Area tanda tangan + Container( + width: double.infinity, + height: 200, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: _signatureImage != null + ? Colors.blue[300]! + : Colors.grey[300]!, + width: _signatureImage != null ? 2 : 1, ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(11), + child: _signatureImage != null + ? Image.memory( + _signatureImage!, + fit: BoxFit.contain, + ) + : Signature( + controller: _signatureController, + backgroundColor: Colors.white, + height: 200, + width: double.infinity, + ), + ), + ), + + // Badge status (jika tanda tangan sudah disimpan) + if (_signatureImage != null) + Positioned( + top: 8, + right: 8, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: Colors.green, + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.check_circle, + color: Colors.white, + size: 14, + ), + const SizedBox(width: 4), + const Text( + 'Tersimpan', + style: TextStyle( + color: Colors.white, + fontSize: 11, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], ), const SizedBox(height: 12), // Tombol aksi untuk tanda tangan Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.center, children: [ // Tombol hapus tanda tangan - ElevatedButton.icon( - onPressed: () { - setState(() { - _signatureController.clear(); - _signatureImage = null; - }); - }, - icon: const Icon(Icons.delete_outline), - label: const Text('Hapus'), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.red[100], - foregroundColor: Colors.red[800], + Expanded( + child: ElevatedButton.icon( + onPressed: () { + setState(() { + _signatureController.clear(); + _signatureImage = null; + }); + }, + icon: const Icon(Icons.delete_outline, size: 18), + label: const Text('Hapus'), + style: ElevatedButton.styleFrom( + foregroundColor: Colors.red[800], + backgroundColor: Colors.red[50], + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + elevation: 0, + ), ), ), + const SizedBox(width: 12), // Tombol simpan tanda tangan - ElevatedButton.icon( - onPressed: _saveSignature, - icon: const Icon(Icons.check), - label: const Text('Simpan'), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green[100], - foregroundColor: Colors.green[800], + Expanded( + child: ElevatedButton.icon( + onPressed: _saveSignature, + icon: const Icon(Icons.check, size: 18), + label: const Text('Simpan'), + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: AppTheme.primaryColor, + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + elevation: 0, + ), ), ), ], @@ -467,69 +1171,192 @@ class _KonfirmasiPenerimaPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'Form Persetujuan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: AppTheme.primaryColor, - ), + Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.teal.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: const Icon( + Icons.gavel_outlined, + color: Colors.teal, + ), + ), + const SizedBox(width: 12), + const Text( + 'Form Persetujuan', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppTheme.primaryColor, + ), + ), + ], ), const SizedBox(height: 16), - // Checkbox persetujuan 1 - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: 24, - height: 24, - child: Checkbox( - value: _setujuPenerimaan, - onChanged: (value) { - setState(() { - _setujuPenerimaan = value ?? false; - }); - }, - activeColor: AppTheme.primaryColor, + // Deskripsi Persetujuan + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.grey[50], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey[200]!), + ), + child: Text( + 'Dengan menandatangani dan mencentang pernyataan berikut, penerima menyatakan telah menerima bantuan sesuai dengan jumlah dan kondisi yang tertera.', + style: TextStyle( + color: Colors.grey[700], + fontSize: 13, + ), + ), + ), + const SizedBox(height: 20), + + // Checkbox persetujuan 1 dengan card + Container( + decoration: BoxDecoration( + color: _setujuPenerimaan ? Colors.green[50] : Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: _setujuPenerimaan + ? Colors.green[300]! + : Colors.grey[300]!, + ), + ), + child: InkWell( + onTap: () { + setState(() { + _setujuPenerimaan = !_setujuPenerimaan; + }); + }, + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 24, + height: 24, + child: Checkbox( + value: _setujuPenerimaan, + onChanged: (value) { + setState(() { + _setujuPenerimaan = value ?? false; + }); + }, + activeColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Pernyataan Penerimaan', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + const Text( + 'Saya telah menerima bantuan dengan jumlah dan kondisi yang sesuai.', + style: TextStyle(fontSize: 13), + ), + ], + ), + ), + if (_setujuPenerimaan) + Icon( + Icons.check_circle, + color: Colors.green[600], + size: 20, + ), + ], ), ), - const SizedBox(width: 12), - const Expanded( - child: Text( - 'Saya telah menerima bantuan dengan jumlah dan kondisi yang sesuai.', - style: TextStyle(fontSize: 14), - ), - ), - ], + ), ), const SizedBox(height: 12), - // Checkbox persetujuan 2 - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: 24, - height: 24, - child: Checkbox( - value: _setujuPenggunaan, - onChanged: (value) { - setState(() { - _setujuPenggunaan = value ?? false; - }); - }, - activeColor: AppTheme.primaryColor, + // Checkbox persetujuan 2 dengan card + Container( + decoration: BoxDecoration( + color: _setujuPenggunaan ? Colors.green[50] : Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: _setujuPenggunaan + ? Colors.green[300]! + : Colors.grey[300]!, + ), + ), + child: InkWell( + onTap: () { + setState(() { + _setujuPenggunaan = !_setujuPenggunaan; + }); + }, + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 24, + height: 24, + child: Checkbox( + value: _setujuPenggunaan, + onChanged: (value) { + setState(() { + _setujuPenggunaan = value ?? false; + }); + }, + activeColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Pernyataan Penggunaan', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + const Text( + 'Saya akan menggunakan bantuan dengan sebaik-baiknya', + style: TextStyle(fontSize: 13), + ), + ], + ), + ), + if (_setujuPenggunaan) + Icon( + Icons.check_circle, + color: Colors.green[600], + size: 20, + ), + ], ), ), - const SizedBox(width: 12), - const Expanded( - child: Text( - 'Saya akan menggunakan bantuan dengan sebaik-baiknya', - style: TextStyle(fontSize: 14), - ), - ), - ], + ), ), ], ), @@ -538,61 +1365,132 @@ class _KonfirmasiPenerimaPageState extends State { } Widget _buildKonfirmasiButton() { - return SizedBox( + final bool isFormValid = _setujuPenerimaan && + _setujuPenggunaan && + _signatureImage != null && + _buktiPenerimaan != null; + + return Container( width: double.infinity, - child: ElevatedButton( - onPressed: _setujuPenerimaan && _setujuPenggunaan - ? _konfirmasiPenerimaan + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + boxShadow: isFormValid + ? [ + BoxShadow( + color: AppTheme.primaryColor.withOpacity(0.3), + blurRadius: 8, + offset: const Offset(0, 4), + ), + ] : null, - style: ElevatedButton.styleFrom( - backgroundColor: AppTheme.primaryColor, - foregroundColor: Colors.white, - padding: const EdgeInsets.symmetric(vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!_setujuPenerimaan || + !_setujuPenggunaan || + _signatureImage == null || + _buktiPenerimaan == null) + Padding( + padding: const EdgeInsets.only(left: 8, bottom: 12), + child: Row( + children: [ + Icon( + Icons.warning_amber_rounded, + color: Colors.orange[700], + size: 18, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + 'Harap lengkapi semua data untuk konfirmasi', + style: TextStyle( + fontSize: 13, + color: Colors.orange[800], + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + + ElevatedButton( + onPressed: isFormValid ? _konfirmasiPenerimaan : null, + style: ElevatedButton.styleFrom( + backgroundColor: AppTheme.primaryColor, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + disabledBackgroundColor: Colors.grey[300], + disabledForegroundColor: Colors.grey[600], + elevation: isFormValid ? 0 : 0, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + isFormValid ? Icons.check_circle_outline : Icons.lock_outline, + size: 20, + ), + const SizedBox(width: 8), + const Text( + 'Konfirmasi Penerimaan', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), ), - disabledBackgroundColor: Colors.grey[300], - disabledForegroundColor: Colors.grey[600], - ), - child: const Text( - 'Konfirmasi Penerimaan', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), + + // Status indikator + if (!isFormValid) + Column( + children: [ + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildStatusIndicator( + _setujuPenerimaan && _setujuPenggunaan, 'Persetujuan'), + const SizedBox(width: 12), + _buildStatusIndicator( + _signatureImage != null, 'Tanda Tangan'), + const SizedBox(width: 12), + _buildStatusIndicator( + _buktiPenerimaan != null, 'Foto Bukti'), + ], + ), + ], + ), + ], ), ); } - Widget _buildInfoRow(String label, String value) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - flex: 2, - child: Text( - label, - style: const TextStyle( - color: Colors.black87, - ), - ), + Widget _buildStatusIndicator(bool isComplete, String label) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + isComplete ? Icons.check_circle : Icons.radio_button_unchecked, + color: isComplete ? Colors.green[600] : Colors.grey[400], + size: 14, + ), + const SizedBox(width: 4), + Text( + label, + style: TextStyle( + fontSize: 12, + color: isComplete ? Colors.green[600] : Colors.grey[600], + fontWeight: isComplete ? FontWeight.w500 : FontWeight.normal, ), - Expanded( - flex: 3, - child: Text( - value, - style: const TextStyle( - fontWeight: FontWeight.w500, - color: Colors.black, - ), - textAlign: TextAlign.right, - ), - ), - ], - ), + ), + ], ); } @@ -719,7 +1617,7 @@ class _KonfirmasiPenerimaPageState extends State { // Konfirmasi penerimaan try { await controller.konfirmasiPenerimaan( - penerima, + penerima!, buktiPenerimaan: imageUrl, tandaTangan: signatureUrl, ); 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 ac1a853..de2d707 100644 --- a/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart +++ b/lib/app/modules/warga/views/warga_detail_penerimaan_view.dart @@ -158,24 +158,6 @@ class WargaDetailPenerimaanView extends GetView { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - penyaluran.namaPenyaluran ?? - penyaluran.keterangan ?? - 'Bantuan', - style: const TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - ], - ), - const SizedBox(height: 16), if (penyaluran.deskripsiPenyaluran != null && penyaluran.deskripsiPenyaluran!.isNotEmpty) Padding( @@ -452,16 +434,6 @@ class WargaDetailPenerimaanView extends GetView { ], ), ], - if (penyaluran.keterangan != null && - penyaluran.keterangan!.isNotEmpty) ...[ - const Divider(height: 24), - _buildDetailItem( - icon: Icons.note, - title: 'Keterangan', - value: penyaluran.keterangan!, - statusColor: null, - ), - ], ], ), ), diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 63e9de9..f78e9ce 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -207,10 +207,15 @@ class AppPages { ), GetPage( name: _Paths.konfirmasiPenerimaQr, - page: () => KonfirmasiPenerimaPage( - penerima: Get.arguments['penerima'], - tanggalPenyaluran: Get.arguments['tanggal_penyaluran'], - ), + page: () { + final penerima = Get.arguments['penerima']; + final String penerimaPenyaluranId = penerima?.id ?? ''; + + return KonfirmasiPenerimaPage( + penerimaPenyaluranId: penerimaPenyaluranId, + tanggalPenyaluran: Get.arguments['tanggal_penyaluran'], + ); + }, binding: PenyaluranBinding(), ), GetPage( diff --git a/lib/app/widgets/bantuan_card.dart b/lib/app/widgets/bantuan_card.dart index f20457c..e074d33 100644 --- a/lib/app/widgets/bantuan_card.dart +++ b/lib/app/widgets/bantuan_card.dart @@ -81,16 +81,6 @@ class BantuanCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text( - item.namaPenyaluran ?? item.keterangan ?? 'Bantuan', - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - const SizedBox(height: 6), Text( item.kategoriNama ?? 'Bantuan', style: TextStyle( @@ -245,22 +235,6 @@ class BantuanCard extends StatelessWidget { ? Colors.green.shade700 : Colors.blue.shade700, ), - const SizedBox(width: 8), - Flexible( - child: Text( - item.namaPenyaluran ?? - item.keterangan ?? - 'Bantuan', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: item.isUang == true - ? Colors.green.shade800 - : Colors.blue.shade800, - ), - overflow: TextOverflow.ellipsis, - ), - ), ], ), ),