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 6f10174..209c1bb 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 4919f33..135389f 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 272cd52..37d37e5 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 a4de62a..fd9b8b4 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/pengaduan_model.dart b/lib/app/data/models/pengaduan_model.dart
index 924c58e..5a50127 100644
--- a/lib/app/data/models/pengaduan_model.dart
+++ b/lib/app/data/models/pengaduan_model.dart
@@ -5,26 +5,28 @@ class PengaduanModel {
   final String? judul;
   final String? deskripsi;
   final String? status;
-  final String? kategori;
-  final String? pelapor;
-  final String? kontakPelapor;
-  final List<String>? gambarUrls;
+  final String? wargaId;
+  final List<dynamic>? fotoPengaduan;
+  final String? penerimaPenyaluranId;
   final DateTime? tanggalPengaduan;
   final DateTime? createdAt;
   final DateTime? updatedAt;
+  final Map<String, dynamic>? penerimaPenyaluran;
+  final Map<String, dynamic>? warga;
 
   PengaduanModel({
     this.id,
     this.judul,
     this.deskripsi,
     this.status,
-    this.kategori,
-    this.pelapor,
-    this.kontakPelapor,
-    this.gambarUrls,
+    this.wargaId,
+    this.fotoPengaduan,
+    this.penerimaPenyaluranId,
     this.tanggalPengaduan,
     this.createdAt,
     this.updatedAt,
+    this.penerimaPenyaluran,
+    this.warga,
   });
 
   factory PengaduanModel.fromRawJson(String str) =>
@@ -37,12 +39,9 @@ class PengaduanModel {
         judul: json["judul"],
         deskripsi: json["deskripsi"],
         status: json["status"],
-        kategori: json["kategori"],
-        pelapor: json["pelapor"],
-        kontakPelapor: json["kontak_pelapor"],
-        gambarUrls: json["gambar_urls"] == null
-            ? null
-            : List<String>.from(json["gambar_urls"].map((x) => x)),
+        wargaId: json["warga_id"],
+        fotoPengaduan: json["foto_pengaduan"],
+        penerimaPenyaluranId: json["penerima_penyaluran_id"],
         tanggalPengaduan: json["tanggal_pengaduan"] != null
             ? DateTime.parse(json["tanggal_pengaduan"])
             : null,
@@ -52,6 +51,8 @@ class PengaduanModel {
         updatedAt: json["updated_at"] != null
             ? DateTime.parse(json["updated_at"])
             : null,
+        penerimaPenyaluran: json["penerima_penyaluran"],
+        warga: json["warga"],
       );
 
   Map<String, dynamic> toJson() => {
@@ -59,14 +60,47 @@ class PengaduanModel {
         "judul": judul,
         "deskripsi": deskripsi,
         "status": status,
-        "kategori": kategori,
-        "pelapor": pelapor,
-        "kontak_pelapor": kontakPelapor,
-        "gambar_urls": gambarUrls == null
-            ? null
-            : List<dynamic>.from(gambarUrls!.map((x) => x)),
+        "warga_id": wargaId,
+        "foto_pengaduan": fotoPengaduan,
+        "penerima_penyaluran_id": penerimaPenyaluranId,
         "tanggal_pengaduan": tanggalPengaduan?.toIso8601String(),
         "created_at": createdAt?.toIso8601String(),
         "updated_at": updatedAt?.toIso8601String(),
+        "penerima_penyaluran": penerimaPenyaluran,
+        "warga": warga,
       };
+
+  // Getter untuk mendapatkan informasi penyaluran bantuan
+  Map<String, dynamic>? get penyaluranBantuan {
+    return penerimaPenyaluran?['penyaluran_bantuan'];
+  }
+
+  // Getter untuk mendapatkan informasi stok bantuan
+  Map<String, dynamic>? get stokBantuan {
+    return penerimaPenyaluran?['stok_bantuan'];
+  }
+
+  // Getter untuk mendapatkan nama penyaluran
+  String get namaPenyaluran {
+    return penyaluranBantuan?['nama'] ?? 'Tidak ada data';
+  }
+
+  // Getter untuk mendapatkan deskripsi penyaluran
+  String get deskripsiPenyaluran {
+    return penyaluranBantuan?['deskripsi'] ?? 'Tidak ada deskripsi';
+  }
+
+  // Getter untuk mendapatkan jenis bantuan
+  String get jenisBantuan {
+    return stokBantuan?['kategori_bantuan']?['nama'] ?? 'Tidak diketahui';
+  }
+
+  // Getter untuk mendapatkan jumlah bantuan yang diterima
+  String get jumlahBantuan {
+    final jumlah = penerimaPenyaluran?['jumlah_bantuan'];
+    final satuan = penerimaPenyaluran?['satuan'] ?? '';
+
+    if (jumlah == null) return 'Tidak diketahui';
+    return '$jumlah $satuan';
+  }
 }
diff --git a/lib/app/data/models/tindakan_pengaduan_model.dart b/lib/app/data/models/tindakan_pengaduan_model.dart
index db73099..b23d319 100644
--- a/lib/app/data/models/tindakan_pengaduan_model.dart
+++ b/lib/app/data/models/tindakan_pengaduan_model.dart
@@ -5,22 +5,46 @@ class TindakanPengaduanModel {
   final String? pengaduanId;
   final String? tindakan;
   final String? catatan;
-  final String? status;
+  final String? statusTindakan; // PROSES, SELESAI
+  final String? prioritas; // RENDAH, SEDANG, TINGGI
+  final String? kategoriTindakan; // Kategori tindakan enum
   final String? petugasId;
+  final String? verifikatorId;
+  final String? hasilTindakan;
+  final List<dynamic>? buktiTindakan;
+  final DateTime? estimasiSelesai;
   final DateTime? tanggalTindakan;
+  final DateTime? tanggalVerifikasi;
   final DateTime? createdAt;
   final DateTime? updatedAt;
+  final double? biayaTindakan;
+  final String? feedbackWarga;
+  final int? ratingWarga;
+  final Map<String, dynamic>? petugas; // Data petugas yang melakukan tindakan
+  final Map<String, dynamic>? verifikator; // Data petugas yang memverifikasi
 
   TindakanPengaduanModel({
     this.id,
     this.pengaduanId,
     this.tindakan,
     this.catatan,
-    this.status,
+    this.statusTindakan,
+    this.prioritas,
+    this.kategoriTindakan,
     this.petugasId,
+    this.verifikatorId,
+    this.hasilTindakan,
+    this.buktiTindakan,
+    this.estimasiSelesai,
     this.tanggalTindakan,
+    this.tanggalVerifikasi,
     this.createdAt,
     this.updatedAt,
+    this.biayaTindakan,
+    this.feedbackWarga,
+    this.ratingWarga,
+    this.petugas,
+    this.verifikator,
   });
 
   factory TindakanPengaduanModel.fromRawJson(String str) =>
@@ -34,17 +58,35 @@ class TindakanPengaduanModel {
         pengaduanId: json["pengaduan_id"],
         tindakan: json["tindakan"],
         catatan: json["catatan"],
-        status: json["status"],
+        statusTindakan: json["status_tindakan"],
+        prioritas: json["prioritas"],
+        kategoriTindakan: json["kategori_tindakan"],
         petugasId: json["petugas_id"],
+        verifikatorId: json["verifikator_id"],
+        hasilTindakan: json["hasil_tindakan"],
+        buktiTindakan: json["bukti_tindakan"],
+        estimasiSelesai: json["estimasi_selesai"] != null
+            ? DateTime.parse(json["estimasi_selesai"])
+            : null,
         tanggalTindakan: json["tanggal_tindakan"] != null
             ? DateTime.parse(json["tanggal_tindakan"])
             : null,
+        tanggalVerifikasi: json["tanggal_verifikasi"] != null
+            ? DateTime.parse(json["tanggal_verifikasi"])
+            : null,
         createdAt: json["created_at"] != null
             ? DateTime.parse(json["created_at"])
             : null,
         updatedAt: json["updated_at"] != null
             ? DateTime.parse(json["updated_at"])
             : null,
+        biayaTindakan: json["biaya_tindakan"] != null
+            ? double.parse(json["biaya_tindakan"].toString())
+            : null,
+        feedbackWarga: json["feedback_warga"],
+        ratingWarga: json["rating_warga"],
+        petugas: json["petugas"],
+        verifikator: json["verifikator"],
       );
 
   Map<String, dynamic> toJson() => {
@@ -52,10 +94,79 @@ class TindakanPengaduanModel {
         "pengaduan_id": pengaduanId,
         "tindakan": tindakan,
         "catatan": catatan,
-        "status": status,
+        "status_tindakan": statusTindakan,
+        "prioritas": prioritas,
+        "kategori_tindakan": kategoriTindakan,
         "petugas_id": petugasId,
+        "verifikator_id": verifikatorId,
+        "hasil_tindakan": hasilTindakan,
+        "bukti_tindakan": buktiTindakan,
+        "estimasi_selesai": estimasiSelesai?.toIso8601String(),
         "tanggal_tindakan": tanggalTindakan?.toIso8601String(),
+        "tanggal_verifikasi": tanggalVerifikasi?.toIso8601String(),
         "created_at": createdAt?.toIso8601String(),
         "updated_at": updatedAt?.toIso8601String(),
+        "biaya_tindakan": biayaTindakan,
+        "feedback_warga": feedbackWarga,
+        "rating_warga": ratingWarga,
+        "petugas": petugas,
+        "verifikator": verifikator,
       };
+
+  // Getter untuk mendapatkan nama petugas
+  String get namaPetugas {
+    if (petugas != null && petugas!['nama'] != null) {
+      return petugas!['nama'];
+    } else if (petugas != null && petugas!['name'] != null) {
+      return petugas!['name'];
+    }
+    return 'Petugas';
+  }
+
+  // Getter untuk mendapatkan nama verifikator
+  String get namaVerifikator {
+    if (verifikator != null && verifikator!['nama'] != null) {
+      return verifikator!['nama'];
+    } else if (verifikator != null && verifikator!['name'] != null) {
+      return verifikator!['name'];
+    }
+    return 'Belum diverifikasi';
+  }
+
+  // Getter untuk mendapatkan status tindakan yang lebih user-friendly
+  String get statusTindakanText {
+    switch (statusTindakan) {
+      case 'PROSES':
+        return 'Dalam Proses';
+      case 'SELESAI':
+        return 'Selesai';
+      default:
+        return statusTindakan ?? 'Tidak Diketahui';
+    }
+  }
+
+  // Getter untuk mendapatkan prioritas yang lebih user-friendly
+  String get prioritasText {
+    switch (prioritas) {
+      case 'RENDAH':
+        return 'Prioritas Rendah';
+      case 'SEDANG':
+        return 'Prioritas Sedang';
+      case 'TINGGI':
+        return 'Prioritas Tinggi';
+      default:
+        return prioritas ?? 'Tidak Diketahui';
+    }
+  }
+
+  // Getter untuk mendapatkan kategori tindakan yang lebih user-friendly
+  String get kategoriTindakanText {
+    if (kategoriTindakan == null) return 'Tidak Diketahui';
+
+    // Mengubah format SNAKE_CASE menjadi Title Case
+    return kategoriTindakan!
+        .split('_')
+        .map((word) => word[0].toUpperCase() + word.substring(1).toLowerCase())
+        .join(' ');
+  }
 }
diff --git a/lib/app/modules/petugas_desa/bindings/pengaduan_binding.dart b/lib/app/modules/petugas_desa/bindings/pengaduan_binding.dart
new file mode 100644
index 0000000..1752f2a
--- /dev/null
+++ b/lib/app/modules/petugas_desa/bindings/pengaduan_binding.dart
@@ -0,0 +1,11 @@
+import 'package:get/get.dart';
+import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pengaduan_controller.dart';
+
+class PengaduanBinding extends Bindings {
+  @override
+  void dependencies() {
+    Get.lazyPut<PengaduanController>(
+      () => PengaduanController(),
+    );
+  }
+}
diff --git a/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart b/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
index 2a1d545..87c84dd 100644
--- a/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
@@ -48,14 +48,15 @@ class PengaduanController extends GetxController {
   Future<void> loadPengaduanData() async {
     isLoading.value = true;
     try {
-      final pengaduanData = await _supabaseService.getPengaduan();
+      final pengaduanData =
+          await _supabaseService.getPengaduanWithPenerimaPenyaluran();
       if (pengaduanData != null) {
         daftarPengaduan.value =
             pengaduanData.map((data) => PengaduanModel.fromJson(data)).toList();
 
         // Hitung jumlah berdasarkan status
         jumlahDiproses.value =
-            daftarPengaduan.where((item) => item.status == 'DIPROSES').length;
+            daftarPengaduan.where((item) => item.status == 'MENUNGGU').length;
         jumlahTindakan.value =
             daftarPengaduan.where((item) => item.status == 'TINDAKAN').length;
         jumlahSelesai.value =
@@ -138,6 +139,36 @@ class PengaduanController extends GetxController {
     }
   }
 
+  Future<void> updateTindakan(
+      String tindakanId, Map<String, dynamic> data) async {
+    isLoading.value = true;
+    try {
+      await _supabaseService.updateTindakanPengaduan(tindakanId, data);
+
+      Get.snackbar(
+        'Sukses',
+        'Tindakan berhasil diperbarui',
+        snackPosition: SnackPosition.TOP,
+        backgroundColor: Colors.green,
+        colorText: Colors.white,
+      );
+
+      // Refresh data
+      Get.forceAppUpdate();
+    } catch (e) {
+      print('Error updating tindakan: $e');
+      Get.snackbar(
+        'Error',
+        'Gagal memperbarui tindakan: ${e.toString()}',
+        snackPosition: SnackPosition.TOP,
+        backgroundColor: Colors.red,
+        colorText: Colors.white,
+      );
+    } finally {
+      isLoading.value = false;
+    }
+  }
+
   Future<void> selesaikanPengaduan(String pengaduanId) async {
     isLoading.value = true;
     try {
@@ -164,6 +195,25 @@ class PengaduanController extends GetxController {
     }
   }
 
+  Future<void> updateStatusPengaduan(String pengaduanId, String status) async {
+    isLoading.value = true;
+    try {
+      await _supabaseService.updateStatusPengaduan(pengaduanId, status);
+      await loadPengaduanData();
+    } catch (e) {
+      print('Error updating pengaduan status: $e');
+      Get.snackbar(
+        'Error',
+        'Gagal mengubah status pengaduan: ${e.toString()}',
+        snackPosition: SnackPosition.TOP,
+        backgroundColor: Colors.red,
+        colorText: Colors.white,
+      );
+    } finally {
+      isLoading.value = false;
+    }
+  }
+
   Future<List<TindakanPengaduanModel>> getTindakanPengaduan(
       String pengaduanId) async {
     try {
@@ -200,7 +250,7 @@ class PengaduanController extends GetxController {
         return daftarPengaduan;
       case 1:
         return daftarPengaduan
-            .where((item) => item.status == 'DIPROSES')
+            .where((item) => item.status == 'MENUNGGU')
             .toList();
       case 2:
         return daftarPengaduan
@@ -222,4 +272,40 @@ class PengaduanController extends GetxController {
     }
     return null;
   }
+
+  Future<Map<String, dynamic>> getDetailPengaduan(String pengaduanId) async {
+    try {
+      // Ambil data pengaduan
+      final pengaduanData =
+          await _supabaseService.client.from('pengaduan').select('''
+            *,
+            penerima_penyaluran:penerima_penyaluran_id(
+              *,
+              penyaluran_bantuan:penyaluran_bantuan_id(*),
+              stok_bantuan:stok_bantuan_id(*),
+              warga:warga_id(*)
+            ),
+            warga:warga_id(*)
+          ''').eq('id', pengaduanId).single();
+
+      // Ambil data tindakan pengaduan
+      final tindakanData =
+          await _supabaseService.getTindakanPengaduan(pengaduanId);
+      print(tindakanData);
+
+      // Gabungkan data
+      final result = {
+        'pengaduan': pengaduanData,
+        'tindakan': tindakanData ?? [],
+      };
+
+      return result;
+    } catch (e) {
+      print('Error getting detail pengaduan: $e');
+      return {
+        'pengaduan': null,
+        'tindakan': [],
+      };
+    }
+  }
 }
diff --git a/lib/app/modules/petugas_desa/views/detail_pengaduan_view.dart b/lib/app/modules/petugas_desa/views/detail_pengaduan_view.dart
new file mode 100644
index 0000000..dbb9585
--- /dev/null
+++ b/lib/app/modules/petugas_desa/views/detail_pengaduan_view.dart
@@ -0,0 +1,2348 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:intl/intl.dart';
+import 'package:penyaluran_app/app/data/models/pengaduan_model.dart';
+import 'package:penyaluran_app/app/data/models/tindakan_pengaduan_model.dart';
+import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pengaduan_controller.dart';
+import 'package:penyaluran_app/app/theme/app_theme.dart';
+import 'package:penyaluran_app/app/widgets/cards/info_card.dart';
+import 'package:penyaluran_app/app/widgets/indicators/status_pill.dart';
+import 'package:penyaluran_app/app/widgets/section_header.dart';
+import 'package:penyaluran_app/app/services/supabase_service.dart';
+import 'package:timeline_tile/timeline_tile.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:supabase_flutter/supabase_flutter.dart';
+import 'dart:io';
+
+class DetailPengaduanView extends GetView<PengaduanController> {
+  const DetailPengaduanView({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final Map<String, dynamic> args = Get.arguments ?? {};
+    final String pengaduanId = args['id'] ?? '';
+
+    if (pengaduanId.isEmpty) {
+      return Scaffold(
+        appBar: AppBar(
+          title: const Text('Detail Pengaduan'),
+        ),
+        body: const Center(
+          child: Text('ID Pengaduan tidak valid'),
+        ),
+      );
+    }
+
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Detail Pengaduan'),
+        elevation: 0,
+        actions: [
+          IconButton(
+            icon: const Icon(Icons.help_outline),
+            onPressed: () {
+              showDialog(
+                context: context,
+                builder: (context) => Dialog(
+                  insetPadding: const EdgeInsets.symmetric(horizontal: 16),
+                  child: SingleChildScrollView(
+                    child: Column(
+                      mainAxisSize: MainAxisSize.min,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.all(16),
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              const Text(
+                                'Panduan',
+                                style: TextStyle(
+                                  fontSize: 18,
+                                  fontWeight: FontWeight.bold,
+                                ),
+                              ),
+                              const SizedBox(height: 16),
+                              _buildStatusGuide(context),
+                            ],
+                          ),
+                        ),
+                        Padding(
+                          padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
+                          child: TextButton(
+                            onPressed: () => Navigator.pop(context),
+                            child: const Text('Tutup'),
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+              );
+            },
+          ),
+        ],
+      ),
+      body: FutureBuilder<Map<String, dynamic>>(
+        future: controller.getDetailPengaduan(pengaduanId),
+        builder: (context, snapshot) {
+          if (snapshot.connectionState == ConnectionState.waiting) {
+            return const Center(child: CircularProgressIndicator());
+          }
+
+          if (snapshot.hasError) {
+            return Center(
+              child: Text('Error: ${snapshot.error}'),
+            );
+          }
+
+          final data = snapshot.data;
+          if (data == null || data['pengaduan'] == null) {
+            return const Center(
+              child: Text('Data pengaduan tidak ditemukan'),
+            );
+          }
+
+          final pengaduan = PengaduanModel.fromJson(data['pengaduan']);
+          final List<TindakanPengaduanModel> tindakanList =
+              (data['tindakan'] as List)
+                  .map((item) => TindakanPengaduanModel.fromJson(item))
+                  .toList();
+
+          return _buildDetailContent(context, pengaduan, tindakanList);
+        },
+      ),
+      floatingActionButton: FloatingActionButton(
+        onPressed: () {
+          _showTambahTindakanDialog(context, pengaduanId);
+        },
+        backgroundColor: AppTheme.primaryColor,
+        child: const Icon(Icons.add),
+      ),
+    );
+  }
+
+  Widget _buildDetailContent(
+    BuildContext context,
+    PengaduanModel pengaduan,
+    List<TindakanPengaduanModel> tindakanList,
+  ) {
+    // Tentukan status dan warna
+    Color statusColor;
+    String statusText;
+
+    switch (pengaduan.status?.toUpperCase()) {
+      case 'MENUNGGU':
+        statusColor = Colors.orange;
+        statusText = 'Menunggu';
+        break;
+      case 'TINDAKAN':
+        statusColor = Colors.blue;
+        statusText = 'Tindakan';
+        break;
+      case 'SELESAI':
+        statusColor = Colors.green;
+        statusText = 'Selesai';
+        break;
+      default:
+        statusColor = Colors.grey;
+        statusText = pengaduan.status ?? 'Tidak Diketahui';
+    }
+
+    return SingleChildScrollView(
+      padding: const EdgeInsets.all(16),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          // Header dengan status
+          _buildHeaderWithStatus(context, pengaduan, statusColor, statusText),
+
+          const SizedBox(height: 24),
+
+          // Informasi pengaduan
+          _buildPengaduanInfo(context, pengaduan),
+
+          const SizedBox(height: 24),
+
+          // Informasi penyaluran yang diadukan
+          if (pengaduan.penerimaPenyaluran != null)
+            _buildPenyaluranInfo(context, pengaduan),
+
+          const SizedBox(height: 24),
+
+          // Timeline tindakan
+          _buildTindakanTimeline(context, tindakanList),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildStatusGuide(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Row(
+          children: [
+            Icon(
+              Icons.info_outline,
+              color: Colors.blue,
+              size: 20,
+            ),
+            const SizedBox(width: 8),
+            const Text(
+              'Alur Status Pengaduan',
+              style: TextStyle(
+                fontSize: 16,
+                fontWeight: FontWeight.bold,
+              ),
+            ),
+          ],
+        ),
+        const SizedBox(height: 16),
+        Container(
+          padding: const EdgeInsets.all(12),
+          decoration: BoxDecoration(
+            color: Colors.grey.shade100,
+            borderRadius: BorderRadius.circular(8),
+          ),
+          child: Column(
+            children: [
+              _buildStatusGuideItem(
+                'MENUNGGU',
+                'Pengaduan baru yang belum ditindaklanjuti',
+                Colors.orange,
+                Icons.hourglass_empty,
+              ),
+              const SizedBox(height: 8),
+              _buildStatusGuideItem(
+                'TINDAKAN',
+                'Pengaduan sedang dalam proses penanganan',
+                Colors.blue,
+                Icons.engineering,
+              ),
+              const SizedBox(height: 8),
+              _buildStatusGuideItem(
+                'SELESAI',
+                'Pengaduan telah selesai ditangani',
+                Colors.green,
+                Icons.check_circle,
+              ),
+            ],
+          ),
+        ),
+        const SizedBox(height: 16),
+        const Divider(),
+        const SizedBox(height: 8),
+        Row(
+          children: [
+            Icon(
+              Icons.info_outline,
+              color: Colors.blue,
+              size: 20,
+            ),
+            const SizedBox(width: 8),
+            const Text(
+              'Status Tindakan',
+              style: TextStyle(
+                fontSize: 16,
+                fontWeight: FontWeight.bold,
+              ),
+            ),
+          ],
+        ),
+        const SizedBox(height: 12),
+        Column(
+          children: [
+            _buildTindakanStatusItem(
+              'PROSES',
+              'Dalam Proses',
+              'Tindakan sedang dilakukan',
+              Colors.blue,
+              Icons.sync,
+            ),
+            const SizedBox(height: 8),
+            _buildTindakanStatusItem(
+              'SELESAI',
+              'Selesai',
+              'Tindakan telah selesai',
+              Colors.green,
+              Icons.check_circle,
+            ),
+          ],
+        ),
+      ],
+    );
+  }
+
+  Widget _buildStatusGuideItem(
+    String status,
+    String description,
+    Color color,
+    IconData icon,
+  ) {
+    return Row(
+      children: [
+        Container(
+          width: 32,
+          height: 32,
+          decoration: BoxDecoration(
+            color: color.withOpacity(0.2),
+            shape: BoxShape.circle,
+          ),
+          child: Center(
+            child: Icon(
+              icon,
+              color: color,
+              size: 18,
+            ),
+          ),
+        ),
+        const SizedBox(width: 12),
+        Expanded(
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              // Menggunakan StatusPill untuk status
+              StatusPill(
+                status: status,
+                backgroundColor: color,
+                textColor: Colors.white,
+              ),
+              const SizedBox(height: 4),
+              Text(
+                description,
+                style: TextStyle(
+                  fontSize: 12,
+                  color: Colors.grey.shade700,
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+
+  Widget _buildTindakanStatusItem(
+    String status,
+    String label,
+    String description,
+    Color color,
+    IconData icon,
+  ) {
+    return Container(
+      padding: const EdgeInsets.all(12),
+      decoration: BoxDecoration(
+        color: color.withOpacity(0.1),
+        borderRadius: BorderRadius.circular(8),
+        border: Border.all(color: color.withOpacity(0.3)),
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Row(
+            children: [
+              Icon(
+                icon,
+                color: color,
+                size: 16,
+              ),
+              const SizedBox(width: 8),
+              // Menggunakan StatusPill untuk status tindakan
+              StatusPill(
+                status: label,
+                backgroundColor: color,
+                textColor: Colors.white,
+              ),
+            ],
+          ),
+          const SizedBox(height: 4),
+          Text(
+            description,
+            style: TextStyle(
+              fontSize: 12,
+              color: Colors.grey.shade700,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildHeaderWithStatus(
+    BuildContext context,
+    PengaduanModel pengaduan,
+    Color statusColor,
+    String statusText,
+  ) {
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Expanded(
+                  child: Text(
+                    pengaduan.judul ?? 'Pengaduan',
+                    style: const TextStyle(
+                      fontSize: 20,
+                      fontWeight: FontWeight.bold,
+                    ),
+                  ),
+                ),
+                // Menggunakan StatusPill untuk menampilkan status
+                _getStatusPill(pengaduan.status),
+              ],
+            ),
+            const SizedBox(height: 12),
+            Text(
+              pengaduan.deskripsi ?? '',
+              style: TextStyle(
+                fontSize: 14,
+                color: Colors.grey.shade700,
+              ),
+            ),
+            const SizedBox(height: 12),
+            Row(
+              children: [
+                Icon(
+                  Icons.calendar_today,
+                  size: 16,
+                  color: Colors.grey.shade600,
+                ),
+                const SizedBox(width: 8),
+                Text(
+                  pengaduan.tanggalPengaduan != null
+                      ? DateFormat('dd MMMM yyyy', 'id_ID')
+                          .format(pengaduan.tanggalPengaduan!)
+                      : '-',
+                  style: TextStyle(
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+              ],
+            ),
+            const SizedBox(height: 16),
+            // Panel status pengaduan
+            _buildStatusPanel(context, pengaduan),
+          ],
+        ),
+      ),
+    );
+  }
+
+  // Helper method untuk mendapatkan StatusPill berdasarkan status
+  StatusPill _getStatusPill(String? status) {
+    switch (status?.toUpperCase()) {
+      case 'MENUNGGU':
+        return StatusPill(
+          status: 'Menunggu',
+          backgroundColor: Colors.orange,
+          textColor: Colors.white,
+          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
+        );
+      case 'TINDAKAN':
+        return StatusPill(
+          status: 'Tindakan',
+          backgroundColor: Colors.blue,
+          textColor: Colors.white,
+          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
+        );
+      case 'SELESAI':
+        return StatusPill.completed(status: 'Selesai');
+      default:
+        return StatusPill(
+          status: status ?? 'Tidak Diketahui',
+          backgroundColor: Colors.grey,
+          textColor: Colors.white,
+          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
+        );
+    }
+  }
+
+  Widget _buildStatusPanel(BuildContext context, PengaduanModel pengaduan) {
+    final status = pengaduan.status?.toUpperCase() ?? '';
+
+    return Container(
+      width: double.infinity,
+      padding: const EdgeInsets.all(12),
+      decoration: BoxDecoration(
+        color: Colors.grey.shade100,
+        borderRadius: BorderRadius.circular(8),
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              const Text(
+                'Status Pengaduan',
+                style: TextStyle(
+                  fontWeight: FontWeight.bold,
+                  fontSize: 14,
+                ),
+              ),
+              // Tambahkan tombol untuk mengubah status
+              if (status != 'SELESAI')
+                TextButton.icon(
+                  onPressed: () {
+                    _showUbahStatusDialog(context, pengaduan);
+                  },
+                  icon: const Icon(Icons.edit, size: 16),
+                  label: const Text('Ubah Status'),
+                  style: TextButton.styleFrom(
+                    padding:
+                        const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
+                    minimumSize: Size.zero,
+                    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  ),
+                ),
+            ],
+          ),
+          const SizedBox(height: 12),
+          Row(
+            children: [
+              Expanded(
+                child: _buildStatusStep(
+                  'MENUNGGU',
+                  'Menunggu',
+                  status == 'MENUNGGU',
+                  status == 'MENUNGGU' ||
+                      status == 'TINDAKAN' ||
+                      status == 'SELESAI',
+                  Colors.orange,
+                ),
+              ),
+              Expanded(
+                child: _buildStatusStep(
+                  'TINDAKAN',
+                  'Tindakan',
+                  status == 'TINDAKAN',
+                  status == 'TINDAKAN' || status == 'SELESAI',
+                  Colors.blue,
+                ),
+              ),
+              Expanded(
+                child: _buildStatusStep(
+                  'SELESAI',
+                  'Selesai',
+                  status == 'SELESAI',
+                  status == 'SELESAI',
+                  Colors.green,
+                ),
+              ),
+            ],
+          ),
+          const SizedBox(height: 16),
+          // Tombol aksi berdasarkan status
+          if (status == 'MENUNGGU')
+            ElevatedButton.icon(
+              onPressed: () {
+                _showTambahTindakanDialog(context, pengaduan.id!);
+              },
+              icon: const Icon(Icons.engineering),
+              label: const Text('Tambah Tindakan'),
+              style: ElevatedButton.styleFrom(
+                backgroundColor: Colors.blue,
+                foregroundColor: Colors.white,
+                minimumSize: const Size(double.infinity, 40),
+              ),
+            )
+          else if (status == 'TINDAKAN')
+            Row(
+              children: [
+                Expanded(
+                  child: ElevatedButton.icon(
+                    onPressed: () {
+                      _showTambahTindakanDialog(context, pengaduan.id!);
+                    },
+                    icon: const Icon(Icons.add),
+                    label: const Text('Tambah Tindakan'),
+                    style: ElevatedButton.styleFrom(
+                      backgroundColor: Colors.blue,
+                      foregroundColor: Colors.white,
+                    ),
+                  ),
+                ),
+                const SizedBox(width: 8),
+                Expanded(
+                  child: ElevatedButton.icon(
+                    onPressed: () {
+                      _showKonfirmasiSelesai(context, pengaduan.id!);
+                    },
+                    icon: const Icon(Icons.check_circle),
+                    label: const Text('Selesaikan'),
+                    style: ElevatedButton.styleFrom(
+                      backgroundColor: Colors.green,
+                      foregroundColor: Colors.white,
+                    ),
+                  ),
+                ),
+              ],
+            )
+          else if (status == 'SELESAI')
+            Container(
+              padding: const EdgeInsets.all(12),
+              decoration: BoxDecoration(
+                color: Colors.green.shade50,
+                borderRadius: BorderRadius.circular(8),
+                border: Border.all(color: Colors.green.shade200),
+              ),
+              child: Row(
+                children: [
+                  Icon(
+                    Icons.check_circle,
+                    color: Colors.green,
+                    size: 20,
+                  ),
+                  const SizedBox(width: 8),
+                  Expanded(
+                    child: Text(
+                      'Pengaduan telah selesai ditangani',
+                      style: TextStyle(
+                        color: Colors.green.shade800,
+                        fontWeight: FontWeight.w500,
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+            ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildStatusStep(
+    String statusValue,
+    String label,
+    bool isActive,
+    bool isCompleted,
+    Color color,
+  ) {
+    return Column(
+      children: [
+        Container(
+          width: 30,
+          height: 30,
+          decoration: BoxDecoration(
+            color: isActive
+                ? color
+                : (isCompleted ? color.withOpacity(0.3) : Colors.grey.shade300),
+            shape: BoxShape.circle,
+          ),
+          child: Center(
+            child: isCompleted
+                ? Icon(
+                    Icons.check,
+                    color: Colors.white,
+                    size: 16,
+                  )
+                : Text(
+                    (statusValue == 'MENUNGGU'
+                        ? '1'
+                        : (statusValue == 'TINDAKAN' ? '2' : '3')),
+                    style: TextStyle(
+                      color: Colors.white,
+                      fontWeight: FontWeight.bold,
+                    ),
+                  ),
+          ),
+        ),
+        const SizedBox(height: 4),
+        Text(
+          label,
+          style: TextStyle(
+            fontSize: 12,
+            fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
+            color: isActive ? color : Colors.grey.shade600,
+          ),
+        ),
+      ],
+    );
+  }
+
+  void _showKonfirmasiSelesai(BuildContext context, String pengaduanId) {
+    showDialog(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: const Text('Konfirmasi'),
+        content: const Text(
+          'Apakah Anda yakin ingin menyelesaikan pengaduan ini? Status pengaduan akan berubah menjadi SELESAI.',
+        ),
+        actions: [
+          TextButton(
+            onPressed: () => Navigator.pop(context),
+            child: const Text('Batal'),
+          ),
+          ElevatedButton(
+            onPressed: () async {
+              await controller.selesaikanPengaduan(pengaduanId);
+              Navigator.pop(context);
+              Get.forceAppUpdate();
+            },
+            style: ElevatedButton.styleFrom(
+              backgroundColor: Colors.green,
+            ),
+            child: const Text('Ya, Selesaikan'),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildPengaduanInfo(BuildContext context, PengaduanModel pengaduan) {
+    final warga = pengaduan.warga;
+    final String namaWarga = warga != null
+        ? warga['nama_lengkap'] ?? 'Tidak diketahui'
+        : 'Tidak diketahui';
+    final String nikWarga = warga != null ? warga['nik'] ?? '-' : '-';
+    final String alamatWarga = warga != null ? warga['alamat'] ?? '-' : '-';
+    final String noHpWarga = warga != null ? warga['no_hp'] ?? '-' : '-';
+
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            // Header dengan judul
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                const Text(
+                  'Informasi Pelapor',
+                  style: TextStyle(
+                    fontSize: 18,
+                    fontWeight: FontWeight.bold,
+                    color: AppTheme.primaryColor,
+                  ),
+                ),
+                Icon(
+                  Icons.person,
+                  color: AppTheme.primaryColor,
+                ),
+              ],
+            ),
+            const Divider(height: 24),
+
+            // Informasi pelapor
+            _buildInfoRow('Nama', namaWarga),
+            _buildInfoRow('NIK', nikWarga),
+            _buildInfoRow('Alamat', alamatWarga),
+            _buildInfoRow('No. HP', noHpWarga),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildPenyaluranInfo(BuildContext context, PengaduanModel pengaduan) {
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            // Header dengan judul
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                const Text(
+                  'Informasi Penyaluran',
+                  style: TextStyle(
+                    fontSize: 18,
+                    fontWeight: FontWeight.bold,
+                    color: AppTheme.primaryColor,
+                  ),
+                ),
+                Icon(
+                  Icons.inventory,
+                  color: AppTheme.primaryColor,
+                ),
+              ],
+            ),
+            const Divider(height: 24),
+
+            // Informasi penyaluran
+            _buildInfoRow('Nama Penyaluran', pengaduan.namaPenyaluran ?? '-'),
+            _buildInfoRow('Jenis Bantuan', pengaduan.jenisBantuan ?? '-'),
+            _buildInfoRow('Jumlah Bantuan', pengaduan.jumlahBantuan ?? '-'),
+            _buildInfoRow('Deskripsi', pengaduan.deskripsiPenyaluran ?? '-'),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildInfoRow(String label, String value) {
+    return Padding(
+      padding: const EdgeInsets.only(bottom: 12.0),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          SizedBox(
+            width: 120,
+            child: Text(
+              label,
+              style: TextStyle(
+                fontSize: 14,
+                color: Colors.grey[600],
+              ),
+            ),
+          ),
+          const SizedBox(width: 8),
+          Expanded(
+            child: Text(
+              value,
+              style: const TextStyle(
+                fontSize: 15,
+                fontWeight: FontWeight.w500,
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildTindakanTimeline(
+    BuildContext context,
+    List<TindakanPengaduanModel> tindakanList,
+  ) {
+    if (tindakanList.isEmpty) {
+      return InfoCard(
+        title: 'Belum Ada Tindakan',
+        description: 'Belum ada tindakan untuk pengaduan ini',
+        icon: Icons.info_outline,
+        backgroundColor: Colors.grey.shade50,
+      );
+    }
+
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            // Menggunakan SectionHeader untuk judul
+            SectionHeader(
+              title: 'Riwayat Tindakan',
+              padding: EdgeInsets.zero,
+            ),
+            const SizedBox(height: 16),
+            ListView.builder(
+              shrinkWrap: true,
+              physics: const NeverScrollableScrollPhysics(),
+              itemCount: tindakanList.length,
+              itemBuilder: (context, index) {
+                final tindakan = tindakanList[index];
+                final bool isFirst = index == 0;
+                final bool isLast = index == tindakanList.length - 1;
+
+                return _buildTimelineTile(
+                  context,
+                  tindakan,
+                  isFirst,
+                  isLast,
+                );
+              },
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildTimelineTile(
+    BuildContext context,
+    TindakanPengaduanModel tindakan,
+    bool isFirst,
+    bool isLast,
+  ) {
+    Color dotColor;
+    switch (tindakan.statusTindakan) {
+      case 'SELESAI':
+        dotColor = Colors.green;
+        break;
+      case 'PROSES':
+        dotColor = Colors.blue;
+        break;
+      default:
+        dotColor = Colors.grey;
+    }
+
+    return TimelineTile(
+      alignment: TimelineAlign.start,
+      isFirst: isFirst,
+      isLast: isLast,
+      indicatorStyle: IndicatorStyle(
+        width: 20,
+        color: dotColor,
+        iconStyle: IconStyle(
+          color: Colors.white,
+          iconData:
+              tindakan.statusTindakan == 'SELESAI' ? Icons.check : Icons.sync,
+        ),
+      ),
+      endChild: Container(
+        margin: const EdgeInsets.only(left: 16, bottom: 24),
+        padding: const EdgeInsets.all(16),
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.circular(8),
+          boxShadow: [
+            BoxShadow(
+              color: Colors.grey.withOpacity(0.1),
+              spreadRadius: 1,
+              blurRadius: 2,
+              offset: const Offset(0, 1),
+            ),
+          ],
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            // Header dengan kategori dan status
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Expanded(
+                  child: Text(
+                    tindakan.kategoriTindakanText,
+                    style: const TextStyle(
+                      fontWeight: FontWeight.bold,
+                      fontSize: 16,
+                    ),
+                  ),
+                ),
+                Row(
+                  children: [
+                    // Menggunakan StatusPill untuk status tindakan
+                    StatusPill(
+                      status: tindakan.statusTindakanText,
+                      backgroundColor: dotColor,
+                      textColor: Colors.white,
+                    ),
+                    const SizedBox(width: 8),
+                    // Tombol edit
+                    InkWell(
+                      onTap: () {
+                        _showEditTindakanDialog(context, tindakan);
+                      },
+                      child: Container(
+                        padding: const EdgeInsets.all(4),
+                        decoration: BoxDecoration(
+                          color: Colors.blue.withOpacity(0.1),
+                          borderRadius: BorderRadius.circular(4),
+                        ),
+                        child: const Icon(
+                          Icons.edit,
+                          size: 16,
+                          color: Colors.blue,
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+            const SizedBox(height: 8),
+
+            // Deskripsi tindakan
+            Text(
+              tindakan.tindakan ?? '',
+              style: const TextStyle(fontSize: 14),
+            ),
+
+            // Catatan tindakan (jika ada)
+            if (tindakan.catatan != null && tindakan.catatan!.isNotEmpty) ...[
+              const SizedBox(height: 8),
+              Text(
+                'Catatan: ${tindakan.catatan}',
+                style: TextStyle(
+                  fontSize: 12,
+                  color: Colors.grey.shade700,
+                  fontStyle: FontStyle.italic,
+                ),
+              ),
+            ],
+
+            // Hasil tindakan (jika ada)
+            if (tindakan.hasilTindakan != null &&
+                tindakan.hasilTindakan!.isNotEmpty) ...[
+              const SizedBox(height: 8),
+              Container(
+                padding: const EdgeInsets.all(8),
+                decoration: BoxDecoration(
+                  color: Colors.blue.shade50,
+                  borderRadius: BorderRadius.circular(4),
+                  border: Border.all(color: Colors.blue.shade100),
+                ),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Row(
+                      children: [
+                        Icon(
+                          Icons.check_circle_outline,
+                          size: 16,
+                          color: Colors.blue.shade700,
+                        ),
+                        const SizedBox(width: 4),
+                        Text(
+                          'Hasil Tindakan:',
+                          style: TextStyle(
+                            fontWeight: FontWeight.bold,
+                            fontSize: 12,
+                            color: Colors.blue.shade700,
+                          ),
+                        ),
+                      ],
+                    ),
+                    const SizedBox(height: 4),
+                    Text(
+                      tindakan.hasilTindakan!,
+                      style: TextStyle(
+                        fontSize: 12,
+                        color: Colors.blue.shade900,
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+            ],
+
+            // Bukti tindakan (jika ada)
+            if (tindakan.buktiTindakan != null &&
+                tindakan.buktiTindakan!.isNotEmpty) ...[
+              const SizedBox(height: 12),
+              Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    'Bukti Tindakan:',
+                    style: TextStyle(
+                      fontSize: 12,
+                      fontWeight: FontWeight.bold,
+                      color: Colors.grey.shade700,
+                    ),
+                  ),
+                  const SizedBox(height: 8),
+                  SingleChildScrollView(
+                    scrollDirection: Axis.horizontal,
+                    child: Row(
+                      children: tindakan.buktiTindakan!.map((bukti) {
+                        return Container(
+                          width: 60,
+                          height: 60,
+                          margin: const EdgeInsets.only(right: 8),
+                          decoration: BoxDecoration(
+                            color: Colors.grey.shade200,
+                            borderRadius: BorderRadius.circular(4),
+                          ),
+                          child: Stack(
+                            children: [
+                              Center(
+                                child: Icon(
+                                  Icons.insert_drive_file,
+                                  color: Colors.blue.shade700,
+                                ),
+                              ),
+                              Positioned(
+                                top: 0,
+                                right: 0,
+                                child: InkWell(
+                                  onTap: () {
+                                    tindakan.buktiTindakan!.remove(bukti);
+                                  },
+                                  child: Container(
+                                    padding: const EdgeInsets.all(2),
+                                    decoration: BoxDecoration(
+                                      color: Colors.red,
+                                      shape: BoxShape.circle,
+                                    ),
+                                    child: const Icon(
+                                      Icons.close,
+                                      color: Colors.white,
+                                      size: 14,
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            ],
+                          ),
+                        );
+                      }).toList(),
+                    ),
+                  ),
+                ],
+              ),
+            ],
+
+            // Feedback warga (jika ada)
+            if (tindakan.feedbackWarga != null &&
+                tindakan.feedbackWarga!.isNotEmpty) ...[
+              const SizedBox(height: 12),
+              Container(
+                padding: const EdgeInsets.all(8),
+                decoration: BoxDecoration(
+                  color: Colors.amber.shade50,
+                  borderRadius: BorderRadius.circular(4),
+                  border: Border.all(color: Colors.amber.shade200),
+                ),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Row(
+                      children: [
+                        Icon(
+                          Icons.comment,
+                          size: 16,
+                          color: Colors.amber.shade800,
+                        ),
+                        const SizedBox(width: 4),
+                        Text(
+                          'Feedback Warga:',
+                          style: TextStyle(
+                            fontWeight: FontWeight.bold,
+                            fontSize: 12,
+                            color: Colors.amber.shade800,
+                          ),
+                        ),
+                        const Spacer(),
+                        if (tindakan.ratingWarga != null) ...[
+                          Row(
+                            children: List.generate(5, (index) {
+                              return Icon(
+                                index < (tindakan.ratingWarga ?? 0)
+                                    ? Icons.star
+                                    : Icons.star_border,
+                                color: Colors.amber,
+                                size: 16,
+                              );
+                            }),
+                          ),
+                        ],
+                      ],
+                    ),
+                    const SizedBox(height: 4),
+                    Text(
+                      tindakan.feedbackWarga!,
+                      style: TextStyle(
+                        fontSize: 13,
+                        color: Colors.amber.shade900,
+                        fontStyle: FontStyle.italic,
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+            ],
+
+            const SizedBox(height: 8),
+
+            // Footer dengan info petugas dan tanggal
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Text(
+                  'Oleh: ${tindakan.namaPetugas}',
+                  style: TextStyle(
+                    fontSize: 12,
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+                Text(
+                  tindakan.tanggalTindakan != null
+                      ? DateFormat('dd MMM yyyy HH:mm', 'id_ID')
+                          .format(tindakan.tanggalTindakan!)
+                      : '-',
+                  style: TextStyle(
+                    fontSize: 12,
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+              ],
+            ),
+
+            // Prioritas tindakan (jika ada)
+            if (tindakan.prioritas != null) ...[
+              const SizedBox(height: 8),
+              // Menggunakan StatusPill untuk prioritas tindakan
+              StatusPill(
+                status: tindakan.prioritasText,
+                backgroundColor: _getPriorityColor(tindakan.prioritas),
+                textColor: Colors.white,
+              ),
+            ],
+          ],
+        ),
+      ),
+    );
+  }
+
+  Color _getPriorityColor(String? priority) {
+    switch (priority) {
+      case 'TINGGI':
+        return Colors.red;
+      case 'SEDANG':
+        return Colors.orange;
+      case 'RENDAH':
+        return Colors.green;
+      default:
+        return Colors.grey;
+    }
+  }
+
+  void _showTambahTindakanDialog(BuildContext context, String pengaduanId) {
+    final formKey = GlobalKey<FormState>();
+    final tindakanController = TextEditingController();
+    final catatanController = TextEditingController();
+    String? selectedKategori;
+    String? selectedPrioritas;
+
+    // Gunakan RxList untuk bukti tindakan
+    final buktiTindakanList = <String>[].obs;
+    final isUploading = false.obs;
+
+    final List<String> kategoriOptions = [
+      'VERIFIKASI_DATA',
+      'KUNJUNGAN_LAPANGAN',
+      'KOORDINASI_LINTAS_INSTANSI',
+      'PERBAIKAN_DATA_PENERIMA',
+      'PENYALURAN_ULANG',
+      'PENGGANTIAN_BANTUAN',
+      'MEDIASI',
+      'KLARIFIKASI',
+      'PENYESUAIAN_JUMLAH_BANTUAN',
+      'PEMERIKSAAN_KUALITAS_BANTUAN',
+      'PERBAIKAN_PROSES_DISTRIBUSI',
+      'EDUKASI_PENERIMA',
+      'PENYELESAIAN_ADMINISTRATIF',
+      'INVESTIGASI_PENYALAHGUNAAN',
+      'PELAPORAN_KE_PIHAK_BERWENANG',
+    ];
+
+    final List<String> prioritasOptions = [
+      'RENDAH',
+      'SEDANG',
+      'TINGGI',
+    ];
+
+    // Fungsi untuk mengunggah bukti tindakan
+    Future<void> uploadBukti() async {
+      try {
+        isUploading.value = true;
+
+        // Buka image picker untuk memilih file
+        final ImagePicker picker = ImagePicker();
+        final XFile? pickedFile = await picker.pickImage(
+          source: ImageSource.gallery,
+          imageQuality: 70,
+        );
+
+        if (pickedFile == null) {
+          isUploading.value = false;
+          return;
+        }
+
+        // Upload file ke Supabase Storage
+        final String filePath = pickedFile.path;
+        final String fileName = filePath.split('/').last;
+        final String fileExt = fileName.split('.').last;
+        final String fileKey =
+            'bukti_tindakan_${DateTime.now().millisecondsSinceEpoch}.$fileExt';
+
+        // Upload ke bucket tindakan_pengaduan
+        await SupabaseService.to.client.storage
+            .from('tindakan_pengaduan')
+            .upload(
+              fileKey,
+              File(filePath),
+              fileOptions:
+                  const FileOptions(cacheControl: '3600', upsert: true),
+            );
+
+        // Dapatkan URL publik
+        final String fileUrl = SupabaseService.to.client.storage
+            .from('tindakan_pengaduan')
+            .getPublicUrl(fileKey);
+
+        // Tambahkan URL ke list bukti
+        buktiTindakanList.add(fileUrl);
+
+        Get.snackbar(
+          'Berhasil',
+          'Bukti berhasil diunggah',
+          snackPosition: SnackPosition.TOP,
+          backgroundColor: Colors.green,
+          colorText: Colors.white,
+        );
+      } catch (e) {
+        print('Error uploading bukti: $e');
+        Get.snackbar(
+          'Error',
+          'Gagal mengunggah bukti: ${e.toString()}',
+          snackPosition: SnackPosition.TOP,
+          backgroundColor: Colors.red,
+          colorText: Colors.white,
+        );
+      } finally {
+        isUploading.value = false;
+      }
+    }
+
+    showDialog(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: const Text('Tambah Tindakan'),
+        content: Form(
+          key: formKey,
+          child: SingleChildScrollView(
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                DropdownButtonFormField<String>(
+                  decoration: const InputDecoration(
+                    labelText: 'Kategori Tindakan',
+                    border: OutlineInputBorder(),
+                  ),
+                  value: selectedKategori,
+                  items: kategoriOptions.map((kategori) {
+                    return DropdownMenuItem<String>(
+                      value: kategori,
+                      child: Text(
+                        kategori
+                            .split('_')
+                            .map((word) =>
+                                word[0].toUpperCase() +
+                                word.substring(1).toLowerCase())
+                            .join(' '),
+                        style: const TextStyle(fontSize: 14),
+                      ),
+                    );
+                  }).toList(),
+                  onChanged: (value) {
+                    selectedKategori = value;
+                  },
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Pilih kategori tindakan';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+                DropdownButtonFormField<String>(
+                  decoration: const InputDecoration(
+                    labelText: 'Prioritas',
+                    border: OutlineInputBorder(),
+                  ),
+                  value: selectedPrioritas,
+                  items: prioritasOptions.map((prioritas) {
+                    return DropdownMenuItem<String>(
+                      value: prioritas,
+                      child: Text(
+                        prioritas[0].toUpperCase() +
+                            prioritas.substring(1).toLowerCase(),
+                        style: const TextStyle(fontSize: 14),
+                      ),
+                    );
+                  }).toList(),
+                  onChanged: (value) {
+                    selectedPrioritas = value;
+                  },
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Pilih prioritas tindakan';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+                TextFormField(
+                  controller: tindakanController,
+                  decoration: const InputDecoration(
+                    labelText: 'Tindakan',
+                    border: OutlineInputBorder(),
+                  ),
+                  maxLines: 3,
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Tindakan tidak boleh kosong';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+                TextFormField(
+                  controller: catatanController,
+                  decoration: const InputDecoration(
+                    labelText: 'Catatan (opsional)',
+                    border: OutlineInputBorder(),
+                  ),
+                  maxLines: 2,
+                ),
+                const SizedBox(height: 16),
+                // Bukti tindakan
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      'Bukti Tindakan:',
+                      style: TextStyle(
+                        fontWeight: FontWeight.bold,
+                        fontSize: 14,
+                        color: Colors.grey.shade800,
+                      ),
+                    ),
+                    const SizedBox(height: 8),
+                    Container(
+                      padding: const EdgeInsets.all(12),
+                      decoration: BoxDecoration(
+                        color: Colors.grey.shade100,
+                        borderRadius: BorderRadius.circular(8),
+                        border: Border.all(color: Colors.grey.shade300),
+                      ),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          Obx(() {
+                            if (buktiTindakanList.isEmpty) {
+                              return const Text(
+                                'Belum ada bukti tindakan',
+                                style: TextStyle(
+                                  fontStyle: FontStyle.italic,
+                                  color: Colors.grey,
+                                ),
+                              );
+                            } else {
+                              return Wrap(
+                                spacing: 8,
+                                runSpacing: 8,
+                                children: buktiTindakanList.map((bukti) {
+                                  return Container(
+                                    width: 80,
+                                    height: 80,
+                                    decoration: BoxDecoration(
+                                      color: Colors.grey.shade200,
+                                      borderRadius: BorderRadius.circular(8),
+                                    ),
+                                    child: Stack(
+                                      children: [
+                                        Center(
+                                          child: Icon(
+                                            Icons.insert_drive_file,
+                                            color: Colors.blue.shade700,
+                                            size: 36,
+                                          ),
+                                        ),
+                                        Positioned(
+                                          top: 0,
+                                          right: 0,
+                                          child: InkWell(
+                                            onTap: () {
+                                              buktiTindakanList.remove(bukti);
+                                            },
+                                            child: Container(
+                                              padding: const EdgeInsets.all(2),
+                                              decoration: BoxDecoration(
+                                                color: Colors.red,
+                                                shape: BoxShape.circle,
+                                              ),
+                                              child: const Icon(
+                                                Icons.close,
+                                                color: Colors.white,
+                                                size: 14,
+                                              ),
+                                            ),
+                                          ),
+                                        ),
+                                      ],
+                                    ),
+                                  );
+                                }).toList(),
+                              );
+                            }
+                          }),
+                          const SizedBox(height: 12),
+                          Obx(() => ElevatedButton.icon(
+                                onPressed:
+                                    isUploading.value ? null : uploadBukti,
+                                icon: isUploading.value
+                                    ? const SizedBox(
+                                        width: 16,
+                                        height: 16,
+                                        child: CircularProgressIndicator(
+                                          strokeWidth: 2,
+                                          color: Colors.white,
+                                        ),
+                                      )
+                                    : const Icon(Icons.upload_file),
+                                label: Text(isUploading.value
+                                    ? 'Mengunggah...'
+                                    : 'Tambah Bukti'),
+                                style: ElevatedButton.styleFrom(
+                                  backgroundColor: Colors.blue,
+                                  foregroundColor: Colors.white,
+                                  minimumSize: const Size(double.infinity, 40),
+                                ),
+                              )),
+                        ],
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        actions: [
+          TextButton(
+            onPressed: () => Navigator.pop(context),
+            child: const Text('Batal'),
+          ),
+          ElevatedButton(
+            onPressed: () async {
+              if (formKey.currentState!.validate()) {
+                try {
+                  // Buat objek tindakan
+                  final Map<String, dynamic> tindakanData = {
+                    'pengaduan_id': pengaduanId,
+                    'tindakan': tindakanController.text,
+                    'catatan': catatanController.text,
+                    'status_tindakan': 'PROSES',
+                    'prioritas': selectedPrioritas,
+                    'kategori_tindakan': selectedKategori,
+                    'tanggal_tindakan': DateTime.now().toIso8601String(),
+                    'petugas_id': controller.user?.id,
+                    'bukti_tindakan': buktiTindakanList.toList(),
+                    'created_at': DateTime.now().toIso8601String(),
+                    'updated_at': DateTime.now().toIso8601String(),
+                  };
+
+                  // Simpan tindakan langsung ke Supabase
+                  await SupabaseService.to
+                      .tambahTindakanPengaduan(tindakanData);
+
+                  // Update status pengaduan
+                  await SupabaseService.to
+                      .updateStatusPengaduan(pengaduanId, 'TINDAKAN');
+
+                  // Tutup dialog
+                  Navigator.pop(context);
+
+                  // Refresh halaman
+                  Get.forceAppUpdate();
+
+                  // Tampilkan snackbar
+                  Get.snackbar(
+                    'Berhasil',
+                    'Tindakan berhasil ditambahkan',
+                    snackPosition: SnackPosition.TOP,
+                    backgroundColor: Colors.green,
+                    colorText: Colors.white,
+                  );
+                } catch (e) {
+                  print('Error adding tindakan: $e');
+                  Get.snackbar(
+                    'Error',
+                    'Gagal menambahkan tindakan: ${e.toString()}',
+                    snackPosition: SnackPosition.TOP,
+                    backgroundColor: Colors.red,
+                    colorText: Colors.white,
+                  );
+                }
+              }
+            },
+            child: const Text('Simpan'),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _showEditTindakanDialog(
+      BuildContext context, TindakanPengaduanModel tindakan) {
+    final formKey = GlobalKey<FormState>();
+    final tindakanController = TextEditingController(text: tindakan.tindakan);
+    final catatanController = TextEditingController(text: tindakan.catatan);
+    final hasilTindakanController =
+        TextEditingController(text: tindakan.hasilTindakan);
+    String? selectedKategori = tindakan.kategoriTindakan;
+    String? selectedPrioritas = tindakan.prioritas;
+    String? selectedStatus = tindakan.statusTindakan;
+
+    // Gunakan RxList untuk bukti tindakan
+    final buktiTindakanList = (tindakan.buktiTindakan ?? []).obs;
+    final isUploading = false.obs;
+
+    final List<String> kategoriOptions = [
+      'VERIFIKASI_DATA',
+      'KUNJUNGAN_LAPANGAN',
+      'KOORDINASI_LINTAS_INSTANSI',
+      'PERBAIKAN_DATA_PENERIMA',
+      'PENYALURAN_ULANG',
+      'PENGGANTIAN_BANTUAN',
+      'MEDIASI',
+      'KLARIFIKASI',
+      'PENYESUAIAN_JUMLAH_BANTUAN',
+      'PEMERIKSAAN_KUALITAS_BANTUAN',
+      'PERBAIKAN_PROSES_DISTRIBUSI',
+      'EDUKASI_PENERIMA',
+      'PENYELESAIAN_ADMINISTRATIF',
+      'INVESTIGASI_PENYALAHGUNAAN',
+      'PELAPORAN_KE_PIHAK_BERWENANG',
+    ];
+
+    final List<String> prioritasOptions = [
+      'RENDAH',
+      'SEDANG',
+      'TINGGI',
+    ];
+
+    final List<String> statusOptions = [
+      'PROSES',
+      'SELESAI',
+    ];
+
+    // Fungsi untuk mengunggah bukti tindakan
+    Future<void> uploadBukti() async {
+      try {
+        isUploading.value = true;
+
+        // Buka image picker untuk memilih file
+        final ImagePicker picker = ImagePicker();
+        final XFile? pickedFile = await picker.pickImage(
+          source: ImageSource.gallery,
+          imageQuality: 70,
+        );
+
+        if (pickedFile == null) {
+          isUploading.value = false;
+          return;
+        }
+
+        // Upload file ke Supabase Storage
+        final String filePath = pickedFile.path;
+        final String fileName = filePath.split('/').last;
+        final String fileExt = fileName.split('.').last;
+        final String fileKey =
+            'bukti_tindakan_${DateTime.now().millisecondsSinceEpoch}.$fileExt';
+
+        // Upload ke bucket tindakan_pengaduan
+        await SupabaseService.to.client.storage
+            .from('tindakan_pengaduan')
+            .upload(
+              fileKey,
+              File(filePath),
+              fileOptions:
+                  const FileOptions(cacheControl: '3600', upsert: true),
+            );
+
+        // Dapatkan URL publik
+        final String fileUrl = SupabaseService.to.client.storage
+            .from('tindakan_pengaduan')
+            .getPublicUrl(fileKey);
+
+        // Tambahkan URL ke list bukti
+        buktiTindakanList.add(fileUrl);
+
+        Get.snackbar(
+          'Berhasil',
+          'Bukti berhasil diunggah',
+          snackPosition: SnackPosition.TOP,
+          backgroundColor: Colors.green,
+          colorText: Colors.white,
+        );
+      } catch (e) {
+        print('Error uploading bukti: $e');
+        Get.snackbar(
+          'Error',
+          'Gagal mengunggah bukti: ${e.toString()}',
+          snackPosition: SnackPosition.TOP,
+          backgroundColor: Colors.red,
+          colorText: Colors.white,
+        );
+      } finally {
+        isUploading.value = false;
+      }
+    }
+
+    showDialog(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: Row(
+          children: [
+            Icon(
+              Icons.edit,
+              color: Colors.blue,
+              size: 24,
+            ),
+            const SizedBox(width: 8),
+            const Text('Edit Tindakan'),
+          ],
+        ),
+        content: Form(
+          key: formKey,
+          child: SingleChildScrollView(
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                // Panel informasi status
+                Container(
+                  width: double.infinity,
+                  padding: const EdgeInsets.all(12),
+                  margin: const EdgeInsets.only(bottom: 16),
+                  decoration: BoxDecoration(
+                    color: Colors.blue.shade50,
+                    borderRadius: BorderRadius.circular(8),
+                    border: Border.all(color: Colors.blue.shade100),
+                  ),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      Text(
+                        'Status Tindakan',
+                        style: TextStyle(
+                          fontWeight: FontWeight.bold,
+                          fontSize: 14,
+                          color: Colors.blue.shade800,
+                        ),
+                      ),
+                      const SizedBox(height: 8),
+                      Text(
+                        'Status tindakan menentukan apakah tindakan ini masih dalam proses atau sudah selesai. Jika semua tindakan selesai, pengaduan dapat diselesaikan.',
+                        style: TextStyle(
+                          fontSize: 12,
+                          color: Colors.blue.shade700,
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+
+                // Status tindakan
+                DropdownButtonFormField<String>(
+                  decoration: InputDecoration(
+                    labelText: 'Status Tindakan',
+                    border: const OutlineInputBorder(),
+                    filled: true,
+                    fillColor: selectedStatus == 'SELESAI'
+                        ? Colors.green.shade50
+                        : Colors.blue.shade50,
+                  ),
+                  value: selectedStatus,
+                  items: statusOptions.map((status) {
+                    return DropdownMenuItem<String>(
+                      value: status,
+                      child: Row(
+                        children: [
+                          Icon(
+                            status == 'PROSES'
+                                ? Icons.sync
+                                : Icons.check_circle,
+                            color:
+                                status == 'PROSES' ? Colors.blue : Colors.green,
+                            size: 18,
+                          ),
+                          const SizedBox(width: 8),
+                          Text(
+                            status == 'PROSES' ? 'Dalam Proses' : 'Selesai',
+                            style: const TextStyle(fontSize: 14),
+                          ),
+                        ],
+                      ),
+                    );
+                  }).toList(),
+                  onChanged: (value) {
+                    selectedStatus = value;
+                  },
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Pilih status tindakan';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+
+                // Kategori tindakan
+                DropdownButtonFormField<String>(
+                  decoration: const InputDecoration(
+                    labelText: 'Kategori Tindakan',
+                    border: OutlineInputBorder(),
+                  ),
+                  value: selectedKategori,
+                  items: kategoriOptions.map((kategori) {
+                    return DropdownMenuItem<String>(
+                      value: kategori,
+                      child: Text(
+                        kategori
+                            .split('_')
+                            .map((word) =>
+                                word[0].toUpperCase() +
+                                word.substring(1).toLowerCase())
+                            .join(' '),
+                        style: const TextStyle(fontSize: 14),
+                      ),
+                    );
+                  }).toList(),
+                  onChanged: (value) {
+                    selectedKategori = value;
+                  },
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Pilih kategori tindakan';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+
+                // Prioritas tindakan
+                DropdownButtonFormField<String>(
+                  decoration: InputDecoration(
+                    labelText: 'Prioritas',
+                    border: const OutlineInputBorder(),
+                    filled: true,
+                    fillColor: selectedPrioritas == 'TINGGI'
+                        ? Colors.red.shade50
+                        : (selectedPrioritas == 'SEDANG'
+                            ? Colors.orange.shade50
+                            : Colors.green.shade50),
+                  ),
+                  value: selectedPrioritas,
+                  items: prioritasOptions.map((prioritas) {
+                    Color priorityColor = prioritas == 'TINGGI'
+                        ? Colors.red
+                        : (prioritas == 'SEDANG'
+                            ? Colors.orange
+                            : Colors.green);
+
+                    return DropdownMenuItem<String>(
+                      value: prioritas,
+                      child: Row(
+                        children: [
+                          Icon(
+                            Icons.flag,
+                            color: priorityColor,
+                            size: 18,
+                          ),
+                          const SizedBox(width: 8),
+                          Text(
+                            prioritas[0].toUpperCase() +
+                                prioritas.substring(1).toLowerCase(),
+                            style: TextStyle(
+                              fontSize: 14,
+                              color: priorityColor,
+                              fontWeight: FontWeight.bold,
+                            ),
+                          ),
+                        ],
+                      ),
+                    );
+                  }).toList(),
+                  onChanged: (value) {
+                    selectedPrioritas = value;
+                  },
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Pilih prioritas tindakan';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+
+                // Deskripsi tindakan
+                TextFormField(
+                  controller: tindakanController,
+                  decoration: const InputDecoration(
+                    labelText: 'Deskripsi Tindakan',
+                    border: OutlineInputBorder(),
+                    hintText: 'Jelaskan tindakan yang dilakukan',
+                  ),
+                  maxLines: 3,
+                  validator: (value) {
+                    if (value == null || value.isEmpty) {
+                      return 'Tindakan tidak boleh kosong';
+                    }
+                    return null;
+                  },
+                ),
+                const SizedBox(height: 16),
+
+                // Catatan tindakan
+                TextFormField(
+                  controller: catatanController,
+                  decoration: const InputDecoration(
+                    labelText: 'Catatan (opsional)',
+                    border: OutlineInputBorder(),
+                    hintText: 'Tambahkan catatan jika diperlukan',
+                  ),
+                  maxLines: 2,
+                ),
+                const SizedBox(height: 16),
+
+                // Hasil tindakan
+                TextFormField(
+                  controller: hasilTindakanController,
+                  decoration: InputDecoration(
+                    labelText: 'Hasil Tindakan',
+                    border: const OutlineInputBorder(),
+                    hintText: 'Jelaskan hasil dari tindakan yang dilakukan',
+                    filled: true,
+                    fillColor: Colors.blue.shade50,
+                  ),
+                  maxLines: 3,
+                ),
+                const SizedBox(height: 16),
+
+                // Bukti tindakan
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      'Bukti Tindakan:',
+                      style: TextStyle(
+                        fontWeight: FontWeight.bold,
+                        fontSize: 14,
+                        color: Colors.grey.shade800,
+                      ),
+                    ),
+                    const SizedBox(height: 8),
+                    Container(
+                      padding: const EdgeInsets.all(12),
+                      decoration: BoxDecoration(
+                        color: Colors.grey.shade100,
+                        borderRadius: BorderRadius.circular(8),
+                        border: Border.all(color: Colors.grey.shade300),
+                      ),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          Obx(() {
+                            if (buktiTindakanList.isEmpty) {
+                              return const Text(
+                                'Belum ada bukti tindakan',
+                                style: TextStyle(
+                                  fontStyle: FontStyle.italic,
+                                  color: Colors.grey,
+                                ),
+                              );
+                            } else {
+                              return Wrap(
+                                spacing: 8,
+                                runSpacing: 8,
+                                children: buktiTindakanList.map((bukti) {
+                                  return Container(
+                                    width: 80,
+                                    height: 80,
+                                    decoration: BoxDecoration(
+                                      color: Colors.grey.shade200,
+                                      borderRadius: BorderRadius.circular(8),
+                                    ),
+                                    child: Stack(
+                                      children: [
+                                        Center(
+                                          child: Icon(
+                                            Icons.insert_drive_file,
+                                            color: Colors.blue.shade700,
+                                            size: 36,
+                                          ),
+                                        ),
+                                        Positioned(
+                                          top: 0,
+                                          right: 0,
+                                          child: InkWell(
+                                            onTap: () {
+                                              buktiTindakanList.remove(bukti);
+                                            },
+                                            child: Container(
+                                              padding: const EdgeInsets.all(2),
+                                              decoration: BoxDecoration(
+                                                color: Colors.red,
+                                                shape: BoxShape.circle,
+                                              ),
+                                              child: const Icon(
+                                                Icons.close,
+                                                color: Colors.white,
+                                                size: 14,
+                                              ),
+                                            ),
+                                          ),
+                                        ),
+                                      ],
+                                    ),
+                                  );
+                                }).toList(),
+                              );
+                            }
+                          }),
+                          const SizedBox(height: 12),
+                          Obx(() => ElevatedButton.icon(
+                                onPressed:
+                                    isUploading.value ? null : uploadBukti,
+                                icon: isUploading.value
+                                    ? const SizedBox(
+                                        width: 16,
+                                        height: 16,
+                                        child: CircularProgressIndicator(
+                                          strokeWidth: 2,
+                                          color: Colors.white,
+                                        ),
+                                      )
+                                    : const Icon(Icons.upload_file),
+                                label: Text(isUploading.value
+                                    ? 'Mengunggah...'
+                                    : 'Tambah Bukti'),
+                                style: ElevatedButton.styleFrom(
+                                  backgroundColor: Colors.blue,
+                                  foregroundColor: Colors.white,
+                                  minimumSize: const Size(double.infinity, 40),
+                                ),
+                              )),
+                        ],
+                      ),
+                    ),
+                  ],
+                ),
+
+                // Informasi tentang feedback warga
+                if (tindakan.feedbackWarga != null &&
+                    tindakan.feedbackWarga!.isNotEmpty) ...[
+                  const SizedBox(height: 16),
+                  Container(
+                    padding: const EdgeInsets.all(12),
+                    decoration: BoxDecoration(
+                      color: Colors.amber.shade50,
+                      borderRadius: BorderRadius.circular(8),
+                      border: Border.all(color: Colors.amber.shade200),
+                    ),
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        Row(
+                          children: [
+                            Icon(
+                              Icons.comment,
+                              color: Colors.amber.shade800,
+                              size: 18,
+                            ),
+                            const SizedBox(width: 8),
+                            Text(
+                              'Feedback dari Warga',
+                              style: TextStyle(
+                                fontWeight: FontWeight.bold,
+                                fontSize: 14,
+                                color: Colors.amber.shade800,
+                              ),
+                            ),
+                          ],
+                        ),
+                        const SizedBox(height: 8),
+                        if (tindakan.ratingWarga != null) ...[
+                          Row(
+                            children: [
+                              Text(
+                                'Rating: ',
+                                style: TextStyle(
+                                  fontSize: 12,
+                                  color: Colors.amber.shade800,
+                                ),
+                              ),
+                              Row(
+                                children: List.generate(5, (index) {
+                                  return Icon(
+                                    index < (tindakan.ratingWarga ?? 0)
+                                        ? Icons.star
+                                        : Icons.star_border,
+                                    color: Colors.amber,
+                                    size: 16,
+                                  );
+                                }),
+                              ),
+                            ],
+                          ),
+                          const SizedBox(height: 4),
+                        ],
+                        Text(
+                          tindakan.feedbackWarga!,
+                          style: TextStyle(
+                            fontSize: 13,
+                            color: Colors.amber.shade900,
+                            fontStyle: FontStyle.italic,
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                ],
+              ],
+            ),
+          ),
+        ),
+        actions: [
+          TextButton(
+            onPressed: () => Navigator.pop(context),
+            child: const Text('Batal'),
+          ),
+          ElevatedButton(
+            onPressed: () async {
+              if (formKey.currentState!.validate()) {
+                try {
+                  // Buat data update
+                  final Map<String, dynamic> updateData = {
+                    'tindakan': tindakanController.text,
+                    'catatan': catatanController.text,
+                    'hasil_tindakan': hasilTindakanController.text,
+                    'status_tindakan': selectedStatus,
+                    'prioritas': selectedPrioritas,
+                    'kategori_tindakan': selectedKategori,
+                    'bukti_tindakan': buktiTindakanList.toList(),
+                    'updated_at': DateTime.now().toIso8601String(),
+                  };
+
+                  // Jika status berubah menjadi SELESAI, tambahkan tanggal verifikasi
+                  if (selectedStatus == 'SELESAI' &&
+                      tindakan.statusTindakan != 'SELESAI') {
+                    updateData['tanggal_verifikasi'] =
+                        DateTime.now().toIso8601String();
+                  }
+
+                  // Update tindakan
+                  await SupabaseService.to
+                      .updateTindakanPengaduan(tindakan.id!, updateData);
+
+                  // Tutup dialog
+                  Navigator.pop(context);
+
+                  // Refresh halaman
+                  Get.forceAppUpdate();
+
+                  // Tampilkan snackbar
+                  Get.snackbar(
+                    'Berhasil',
+                    'Tindakan berhasil diperbarui',
+                    snackPosition: SnackPosition.TOP,
+                    backgroundColor: Colors.green,
+                    colorText: Colors.white,
+                  );
+                } catch (e) {
+                  print('Error updating tindakan: $e');
+                  Get.snackbar(
+                    'Error',
+                    'Gagal memperbarui tindakan: ${e.toString()}',
+                    snackPosition: SnackPosition.TOP,
+                    backgroundColor: Colors.red,
+                    colorText: Colors.white,
+                  );
+                }
+              }
+            },
+            style: ElevatedButton.styleFrom(
+              backgroundColor: Colors.green,
+            ),
+            child: const Text('Simpan Perubahan'),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _showUbahStatusDialog(BuildContext context, PengaduanModel pengaduan) {
+    final String currentStatus = pengaduan.status?.toUpperCase() ?? '';
+    String selectedStatus = currentStatus;
+
+    final List<String> statusOptions = [
+      'MENUNGGU',
+      'TINDAKAN',
+      'SELESAI',
+    ];
+
+    // Hapus status yang sama dengan status saat ini dari opsi
+    statusOptions.remove(currentStatus);
+
+    showDialog(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: const Text('Ubah Status Pengaduan'),
+        content: Column(
+          mainAxisSize: MainAxisSize.min,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const Text(
+              'Status saat ini:',
+              style: TextStyle(
+                fontSize: 14,
+                color: Colors.grey,
+              ),
+            ),
+            const SizedBox(height: 8),
+            _getStatusPill(currentStatus),
+            const SizedBox(height: 16),
+            const Text(
+              'Pilih status baru:',
+              style: TextStyle(
+                fontSize: 14,
+                fontWeight: FontWeight.bold,
+              ),
+            ),
+            const SizedBox(height: 8),
+            ...statusOptions.map((status) => RadioListTile<String>(
+                  title: Text(
+                    status == 'MENUNGGU'
+                        ? 'Menunggu'
+                        : (status == 'TINDAKAN' ? 'Tindakan' : 'Selesai'),
+                  ),
+                  value: status,
+                  groupValue: selectedStatus,
+                  onChanged: (value) {
+                    selectedStatus = value!;
+                    Navigator.pop(context);
+                    _showKonfirmasiUbahStatus(
+                        context, pengaduan.id!, selectedStatus);
+                  },
+                  activeColor: status == 'MENUNGGU'
+                      ? Colors.orange
+                      : (status == 'TINDAKAN' ? Colors.blue : Colors.green),
+                  secondary: Icon(
+                    status == 'MENUNGGU'
+                        ? Icons.hourglass_empty
+                        : (status == 'TINDAKAN'
+                            ? Icons.engineering
+                            : Icons.check_circle),
+                    color: status == 'MENUNGGU'
+                        ? Colors.orange
+                        : (status == 'TINDAKAN' ? Colors.blue : Colors.green),
+                  ),
+                )),
+          ],
+        ),
+        actions: [
+          TextButton(
+            onPressed: () => Navigator.pop(context),
+            child: const Text('Batal'),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _showKonfirmasiUbahStatus(
+      BuildContext context, String pengaduanId, String newStatus) {
+    String statusText = newStatus == 'MENUNGGU'
+        ? 'Menunggu'
+        : (newStatus == 'TINDAKAN' ? 'Tindakan' : 'Selesai');
+
+    Color statusColor = newStatus == 'MENUNGGU'
+        ? Colors.orange
+        : (newStatus == 'TINDAKAN' ? Colors.blue : Colors.green);
+
+    showDialog(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: const Text('Konfirmasi'),
+        content: Column(
+          mainAxisSize: MainAxisSize.min,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Text(
+              'Apakah Anda yakin ingin mengubah status pengaduan menjadi "$statusText"?',
+            ),
+            const SizedBox(height: 16),
+            if (newStatus == 'SELESAI')
+              Container(
+                padding: const EdgeInsets.all(12),
+                decoration: BoxDecoration(
+                  color: Colors.amber.shade50,
+                  borderRadius: BorderRadius.circular(8),
+                  border: Border.all(color: Colors.amber.shade200),
+                ),
+                child: Row(
+                  children: [
+                    Icon(
+                      Icons.warning,
+                      color: Colors.amber.shade800,
+                      size: 20,
+                    ),
+                    const SizedBox(width: 8),
+                    Expanded(
+                      child: Text(
+                        'Mengubah status menjadi Selesai akan menandai pengaduan ini telah selesai ditangani.',
+                        style: TextStyle(
+                          fontSize: 12,
+                          color: Colors.amber.shade800,
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+          ],
+        ),
+        actions: [
+          TextButton(
+            onPressed: () => Navigator.pop(context),
+            child: const Text('Batal'),
+          ),
+          ElevatedButton(
+            onPressed: () async {
+              if (newStatus == 'SELESAI') {
+                await controller.selesaikanPengaduan(pengaduanId);
+              } else {
+                // Gunakan fungsi prosesPengaduan untuk status TINDAKAN
+                // atau fungsi khusus untuk status lainnya
+                if (newStatus == 'TINDAKAN') {
+                  await controller.prosesPengaduan(pengaduanId);
+                } else {
+                  // Tambahkan fungsi updateStatusPengaduan di controller
+                  await controller.updateStatusPengaduan(
+                      pengaduanId, newStatus);
+                }
+              }
+
+              Navigator.pop(context);
+              Get.forceAppUpdate();
+
+              Get.snackbar(
+                'Berhasil',
+                'Status pengaduan berhasil diubah menjadi $statusText',
+                snackPosition: SnackPosition.TOP,
+                backgroundColor: statusColor,
+                colorText: Colors.white,
+              );
+            },
+            style: ElevatedButton.styleFrom(
+              backgroundColor: statusColor,
+            ),
+            child: const Text('Ya, Ubah Status'),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/app/modules/petugas_desa/views/pengaduan_view.dart b/lib/app/modules/petugas_desa/views/pengaduan_view.dart
index 050eff7..2b2a5e4 100644
--- a/lib/app/modules/petugas_desa/views/pengaduan_view.dart
+++ b/lib/app/modules/petugas_desa/views/pengaduan_view.dart
@@ -1,9 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
-import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_controller.dart';
+import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pengaduan_controller.dart';
 import 'package:penyaluran_app/app/theme/app_theme.dart';
+import 'package:penyaluran_app/app/utils/date_time_helper.dart';
 
-class PengaduanView extends GetView<PetugasDesaController> {
+class PengaduanView extends GetView<PengaduanController> {
   const PengaduanView({super.key});
 
   @override
@@ -33,58 +34,60 @@ class PengaduanView extends GetView<PetugasDesaController> {
   }
 
   Widget _buildPengaduanSummary(BuildContext context) {
-    return Container(
-      width: double.infinity,
-      padding: const EdgeInsets.all(16),
-      decoration: BoxDecoration(
-        gradient: AppTheme.primaryGradient,
-        borderRadius: BorderRadius.circular(12),
-      ),
-      child: Column(
-        crossAxisAlignment: CrossAxisAlignment.start,
-        children: [
-          Text(
-            'Ringkasan Pengaduan',
-            style: Theme.of(context).textTheme.titleLarge?.copyWith(
-                  fontWeight: FontWeight.bold,
-                  color: Colors.white,
+    return Obx(() {
+      return Container(
+        width: double.infinity,
+        padding: const EdgeInsets.all(16),
+        decoration: BoxDecoration(
+          gradient: AppTheme.primaryGradient,
+          borderRadius: BorderRadius.circular(12),
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Text(
+              'Ringkasan Pengaduan',
+              style: Theme.of(context).textTheme.titleLarge?.copyWith(
+                    fontWeight: FontWeight.bold,
+                    color: Colors.white,
+                  ),
+            ),
+            const SizedBox(height: 16),
+            Row(
+              children: [
+                Expanded(
+                  child: _buildSummaryItem(
+                    context,
+                    icon: Icons.pending_actions,
+                    title: 'Diproses',
+                    value: controller.jumlahDiproses.toString(),
+                    color: Colors.orange,
+                  ),
                 ),
-          ),
-          const SizedBox(height: 16),
-          Row(
-            children: [
-              Expanded(
-                child: _buildSummaryItem(
-                  context,
-                  icon: Icons.pending_actions,
-                  title: 'Diproses',
-                  value: '3',
-                  color: Colors.orange,
+                Expanded(
+                  child: _buildSummaryItem(
+                    context,
+                    icon: Icons.engineering,
+                    title: 'Tindakan',
+                    value: controller.jumlahTindakan.toString(),
+                    color: Colors.blue,
+                  ),
                 ),
-              ),
-              Expanded(
-                child: _buildSummaryItem(
-                  context,
-                  icon: Icons.engineering,
-                  title: 'Tindakan',
-                  value: '2',
-                  color: Colors.blue,
+                Expanded(
+                  child: _buildSummaryItem(
+                    context,
+                    icon: Icons.check_circle,
+                    title: 'Selesai',
+                    value: controller.jumlahSelesai.toString(),
+                    color: Colors.green,
+                  ),
                 ),
-              ),
-              Expanded(
-                child: _buildSummaryItem(
-                  context,
-                  icon: Icons.check_circle,
-                  title: 'Selesai',
-                  value: '8',
-                  color: Colors.green,
-                ),
-              ),
-            ],
-          ),
-        ],
-      ),
-    );
+              ],
+            ),
+          ],
+        ),
+      );
+    });
   }
 
   Widget _buildSummaryItem(
@@ -133,6 +136,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
       children: [
         Expanded(
           child: TextField(
+            controller: controller.searchController,
             decoration: InputDecoration(
               hintText: 'Cari pengaduan...',
               prefixIcon: const Icon(Icons.search),
@@ -144,6 +148,10 @@ class PengaduanView extends GetView<PetugasDesaController> {
               fillColor: Colors.grey.shade100,
               contentPadding: const EdgeInsets.symmetric(vertical: 0),
             ),
+            onChanged: (value) {
+              // Implementasi pencarian
+              controller.refreshData();
+            },
           ),
         ),
         const SizedBox(width: 12),
@@ -173,21 +181,42 @@ class PengaduanView extends GetView<PetugasDesaController> {
         content: Column(
           mainAxisSize: MainAxisSize.min,
           children: [
-            CheckboxListTile(
-              title: const Text('Diproses'),
-              value: true,
-              onChanged: (value) {},
-            ),
-            CheckboxListTile(
-              title: const Text('Tindakan'),
-              value: true,
-              onChanged: (value) {},
-            ),
-            CheckboxListTile(
-              title: const Text('Selesai'),
-              value: true,
-              onChanged: (value) {},
-            ),
+            Obx(() => RadioListTile<int>(
+                  title: const Text('Semua'),
+                  value: 0,
+                  groupValue: controller.selectedCategoryIndex.value,
+                  onChanged: (value) {
+                    controller.changeCategory(value!);
+                    Navigator.pop(context);
+                  },
+                )),
+            Obx(() => RadioListTile<int>(
+                  title: const Text('Diproses'),
+                  value: 1,
+                  groupValue: controller.selectedCategoryIndex.value,
+                  onChanged: (value) {
+                    controller.changeCategory(value!);
+                    Navigator.pop(context);
+                  },
+                )),
+            Obx(() => RadioListTile<int>(
+                  title: const Text('Tindakan'),
+                  value: 2,
+                  groupValue: controller.selectedCategoryIndex.value,
+                  onChanged: (value) {
+                    controller.changeCategory(value!);
+                    Navigator.pop(context);
+                  },
+                )),
+            Obx(() => RadioListTile<int>(
+                  title: const Text('Selesai'),
+                  value: 3,
+                  groupValue: controller.selectedCategoryIndex.value,
+                  onChanged: (value) {
+                    controller.changeCategory(value!);
+                    Navigator.pop(context);
+                  },
+                )),
           ],
         ),
         actions: [
@@ -195,84 +224,85 @@ class PengaduanView extends GetView<PetugasDesaController> {
             onPressed: () => Navigator.pop(context),
             child: const Text('Batal'),
           ),
-          ElevatedButton(
-            onPressed: () => Navigator.pop(context),
-            child: const Text('Terapkan'),
-          ),
         ],
       ),
     );
   }
 
   Widget _buildPengaduanList(BuildContext context) {
-    final List<Map<String, dynamic>> pengaduanList = [
-      {
-        'id': '1',
-        'nama': 'Budi Santoso',
-        'nik': '3201020107030011',
-        'jenis_pengaduan': 'Bantuan Tidak Diterima',
-        'deskripsi':
-            'Saya belum menerima bantuan beras yang dijadwalkan minggu lalu',
-        'tanggal': '15 April 2023',
-        'status': 'Diproses',
-      },
-      {
-        'id': '2',
-        'nama': 'Siti Rahayu',
-        'nik': '3201020107030010',
-        'jenis_pengaduan': 'Kualitas Bantuan',
-        'deskripsi':
-            'Beras yang diterima berkualitas buruk dan tidak layak konsumsi',
-        'tanggal': '14 April 2023',
-        'status': 'Tindakan',
-      },
-      {
-        'id': '3',
-        'nama': 'Ahmad Fauzi',
-        'nik': '3201020107030013',
-        'jenis_pengaduan': 'Jumlah Bantuan',
-        'deskripsi':
-            'Jumlah bantuan yang diterima tidak sesuai dengan yang dijanjikan',
-        'tanggal': '13 April 2023',
-        'status': 'Tindakan',
-      },
-      {
-        'id': '4',
-        'nama': 'Dewi Lestari',
-        'nik': '3201020107030012',
-        'jenis_pengaduan': 'Jadwal Penyaluran',
-        'deskripsi':
-            'Jadwal penyaluran bantuan sering berubah tanpa pemberitahuan',
-        'tanggal': '10 April 2023',
-        'status': 'Selesai',
-      },
-    ];
+    return Obx(() {
+      if (controller.isLoading.value) {
+        return const Center(
+          child: Padding(
+            padding: EdgeInsets.all(20.0),
+            child: CircularProgressIndicator(),
+          ),
+        );
+      }
 
-    return Column(
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text(
-          'Daftar Pengaduan',
-          style: Theme.of(context).textTheme.titleLarge?.copyWith(
-                fontWeight: FontWeight.bold,
+      final filteredPengaduan = controller.getFilteredPengaduan();
+
+      if (filteredPengaduan.isEmpty) {
+        return Center(
+          child: Padding(
+            padding: const EdgeInsets.all(20.0),
+            child: Column(
+              children: [
+                const Icon(
+                  Icons.inbox_outlined,
+                  size: 80,
+                  color: Colors.grey,
+                ),
+                const SizedBox(height: 16),
+                Text(
+                  'Belum ada pengaduan',
+                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
+                        color: Colors.grey,
+                      ),
+                ),
+              ],
+            ),
+          ),
+        );
+      }
+
+      return Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                'Daftar Pengaduan',
+                style: Theme.of(context).textTheme.titleLarge?.copyWith(
+                      fontWeight: FontWeight.bold,
+                    ),
               ),
-        ),
-        const SizedBox(height: 12),
-        ...pengaduanList.map((item) => _buildPengaduanItem(context, item)),
-      ],
-    );
+              IconButton(
+                icon: const Icon(Icons.refresh),
+                onPressed: () => controller.refreshData(),
+                tooltip: 'Refresh',
+              ),
+            ],
+          ),
+          const SizedBox(height: 12),
+          ...filteredPengaduan
+              .map((item) => _buildPengaduanItem(context, item)),
+        ],
+      );
+    });
   }
 
-  Widget _buildPengaduanItem(BuildContext context, Map<String, dynamic> item) {
+  Widget _buildPengaduanItem(BuildContext context, dynamic item) {
     Color statusColor;
     IconData statusIcon;
 
-    switch (item['status']) {
+    switch (item.status?.toUpperCase()) {
       case 'MENUNGGU':
         statusColor = AppTheme.warningColor;
         statusIcon = Icons.pending;
         break;
-      case 'DIPROSES':
+      case 'TINDAKAN':
         statusColor = AppTheme.infoColor;
         statusIcon = Icons.sync;
         break;
@@ -285,6 +315,14 @@ class PengaduanView extends GetView<PetugasDesaController> {
         statusIcon = Icons.help_outline;
     }
 
+    // Format tanggal menggunakan DateTimeHelper
+    String formattedDate = '';
+    if (item.tanggalPengaduan != null) {
+      formattedDate = DateTimeHelper.formatDate(item.tanggalPengaduan);
+    } else if (item.createdAt != null) {
+      formattedDate = DateTimeHelper.formatDate(item.createdAt);
+    }
+
     return Container(
       width: double.infinity,
       margin: const EdgeInsets.only(bottom: 12),
@@ -310,7 +348,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
               children: [
                 Expanded(
                   child: Text(
-                    item['nama'] ?? '',
+                    item.warga?['nama'] ?? item.judul ?? '',
                     style: Theme.of(context).textTheme.titleMedium?.copyWith(
                           fontWeight: FontWeight.bold,
                         ),
@@ -334,7 +372,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
                       ),
                       const SizedBox(width: 4),
                       Text(
-                        item['status'] ?? '',
+                        item.status ?? '',
                         style: Theme.of(context).textTheme.bodySmall?.copyWith(
                               color: statusColor,
                               fontWeight: FontWeight.bold,
@@ -347,28 +385,64 @@ class PengaduanView extends GetView<PetugasDesaController> {
             ),
             const SizedBox(height: 4),
             Text(
-              'NIK: ${item['nik'] ?? ''}',
+              'NIK: ${item.warga?['nik'] ?? ''}',
               style: Theme.of(context).textTheme.bodySmall?.copyWith(
                     color: Colors.grey,
                   ),
             ),
             const SizedBox(height: 12),
-            Container(
-              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
-              decoration: BoxDecoration(
-                color: Colors.grey.shade100,
-                borderRadius: BorderRadius.circular(4),
+            if (item.penerimaPenyaluran != null) ...[
+              Container(
+                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
+                decoration: BoxDecoration(
+                  color: Colors.grey.shade100,
+                  borderRadius: BorderRadius.circular(4),
+                ),
+                child: Text(
+                  'Penyaluran: ${item.namaPenyaluran}',
+                  style: Theme.of(context).textTheme.bodySmall?.copyWith(
+                        fontWeight: FontWeight.bold,
+                      ),
+                ),
               ),
-              child: Text(
-                item['jenis_pengaduan'] ?? '',
-                style: Theme.of(context).textTheme.bodySmall?.copyWith(
-                      fontWeight: FontWeight.bold,
+              const SizedBox(height: 8),
+              Row(
+                children: [
+                  Expanded(
+                    child: Container(
+                      padding: const EdgeInsets.symmetric(
+                          horizontal: 8, vertical: 4),
+                      decoration: BoxDecoration(
+                        color: Colors.blue.shade50,
+                        borderRadius: BorderRadius.circular(4),
+                      ),
+                      child: Text(
+                        'Jenis: ${item.jenisBantuan}',
+                        style: Theme.of(context).textTheme.bodySmall,
+                      ),
                     ),
+                  ),
+                  const SizedBox(width: 8),
+                  Expanded(
+                    child: Container(
+                      padding: const EdgeInsets.symmetric(
+                          horizontal: 8, vertical: 4),
+                      decoration: BoxDecoration(
+                        color: Colors.green.shade50,
+                        borderRadius: BorderRadius.circular(4),
+                      ),
+                      child: Text(
+                        'Jumlah: ${item.jumlahBantuan}',
+                        style: Theme.of(context).textTheme.bodySmall,
+                      ),
+                    ),
+                  ),
+                ],
               ),
-            ),
+            ],
             const SizedBox(height: 8),
             Text(
-              item['deskripsi'] ?? '',
+              item.deskripsi ?? '',
               style: Theme.of(context).textTheme.bodyMedium,
               maxLines: 2,
               overflow: TextOverflow.ellipsis,
@@ -383,7 +457,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
                 ),
                 const SizedBox(width: 4),
                 Text(
-                  item['tanggal'] ?? '',
+                  formattedDate,
                   style: Theme.of(context).textTheme.bodySmall?.copyWith(
                         color: Colors.grey,
                       ),
@@ -401,11 +475,10 @@ class PengaduanView extends GetView<PetugasDesaController> {
     );
   }
 
-  List<Widget> _buildActionButtons(
-      BuildContext context, Map<String, dynamic> item) {
-    final status = item['status'];
+  List<Widget> _buildActionButtons(BuildContext context, dynamic item) {
+    final status = item.status?.toUpperCase();
 
-    if (status == 'Diproses') {
+    if (status == 'MENUNGGU') {
       return [
         TextButton.icon(
           onPressed: () {
@@ -421,8 +494,8 @@ class PengaduanView extends GetView<PetugasDesaController> {
         ),
         TextButton.icon(
           onPressed: () {
-            // Implementasi untuk melihat detail pengaduan
-            _showDetailDialog(context, item);
+            // Navigasi ke halaman detail pengaduan
+            Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
           },
           icon: const Icon(Icons.info_outline, size: 18),
           label: const Text('Detail'),
@@ -432,7 +505,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
           ),
         ),
       ];
-    } else if (status == 'Tindakan') {
+    } else if (status == 'TINDAKAN') {
       return [
         TextButton.icon(
           onPressed: () {
@@ -448,8 +521,8 @@ class PengaduanView extends GetView<PetugasDesaController> {
         ),
         TextButton.icon(
           onPressed: () {
-            // Implementasi untuk melihat detail pengaduan
-            _showDetailDialog(context, item);
+            // Navigasi ke halaman detail pengaduan
+            Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
           },
           icon: const Icon(Icons.info_outline, size: 18),
           label: const Text('Detail'),
@@ -463,8 +536,8 @@ class PengaduanView extends GetView<PetugasDesaController> {
       return [
         TextButton.icon(
           onPressed: () {
-            // Implementasi untuk melihat detail pengaduan
-            _showDetailDialog(context, item);
+            // Navigasi ke halaman detail pengaduan
+            Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
           },
           icon: const Icon(Icons.info_outline, size: 18),
           label: const Text('Detail'),
@@ -477,103 +550,41 @@ class PengaduanView extends GetView<PetugasDesaController> {
     }
   }
 
-  void _showDetailDialog(BuildContext context, Map<String, dynamic> item) {
-    showDialog(
-      context: context,
-      builder: (context) => AlertDialog(
-        title: Text('Detail Pengaduan: ${item['id']}'),
-        content: SingleChildScrollView(
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.start,
-            mainAxisSize: MainAxisSize.min,
-            children: [
-              _buildDetailItem('Nama', item['nama'] ?? ''),
-              _buildDetailItem('NIK', item['nik'] ?? ''),
-              _buildDetailItem(
-                  'Jenis Pengaduan', item['jenis_pengaduan'] ?? ''),
-              _buildDetailItem('Tanggal', item['tanggal'] ?? ''),
-              _buildDetailItem('Status', item['status'] ?? ''),
-              const SizedBox(height: 8),
-              const Text(
-                'Deskripsi:',
-                style: TextStyle(fontWeight: FontWeight.bold),
-              ),
-              const SizedBox(height: 4),
-              Text(item['deskripsi'] ?? ''),
-              if (item['status'] == 'Tindakan' ||
-                  item['status'] == 'Selesai') ...[
-                const SizedBox(height: 8),
-                const Text(
-                  'Tindakan:',
-                  style: TextStyle(fontWeight: FontWeight.bold),
-                ),
-                const SizedBox(height: 4),
-                Text(item['tindakan'] ??
-                    'Pengecekan ke lokasi dan verifikasi data penerima'),
-              ],
-              if (item['status'] == 'Selesai') ...[
-                const SizedBox(height: 8),
-                const Text(
-                  'Hasil:',
-                  style: TextStyle(fontWeight: FontWeight.bold),
-                ),
-                const SizedBox(height: 4),
-                Text(item['hasil'] ??
-                    'Pengaduan telah diselesaikan dengan penyaluran ulang bantuan'),
-              ],
-            ],
-          ),
-        ),
-        actions: [
-          TextButton(
-            onPressed: () => Navigator.pop(context),
-            child: const Text('Tutup'),
-          ),
-        ],
-      ),
-    );
-  }
-
-  Widget _buildDetailItem(String label, String value) {
-    return Padding(
-      padding: const EdgeInsets.only(bottom: 8.0),
-      child: Row(
-        crossAxisAlignment: CrossAxisAlignment.start,
-        children: [
-          SizedBox(
-            width: 120,
-            child: Text(
-              '$label:',
-              style: const TextStyle(fontWeight: FontWeight.bold),
-            ),
-          ),
-          Expanded(child: Text(value)),
-        ],
-      ),
-    );
-  }
-
-  void _showTindakanDialog(BuildContext context, Map<String, dynamic> item) {
-    final TextEditingController tindakanController = TextEditingController();
+  void _showTindakanDialog(BuildContext context, dynamic item) {
+    controller.tindakanController.clear();
+    controller.catatanController.clear();
 
     showDialog(
       context: context,
       builder: (context) => AlertDialog(
         title: const Text('Tindakan Pengaduan'),
-        content: Column(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            Text('Pengaduan dari: ${item['nama']}'),
-            const SizedBox(height: 16),
-            TextField(
-              controller: tindakanController,
-              decoration: const InputDecoration(
-                labelText: 'Tindakan yang dilakukan',
-                border: OutlineInputBorder(),
+        content: Form(
+          key: controller.tindakanFormKey,
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Text('Pengaduan dari: ${item.warga?['nama'] ?? ''}'),
+              const SizedBox(height: 16),
+              TextFormField(
+                controller: controller.tindakanController,
+                decoration: const InputDecoration(
+                  labelText: 'Tindakan yang dilakukan',
+                  border: OutlineInputBorder(),
+                ),
+                maxLines: 3,
+                validator: controller.validateTindakan,
               ),
-              maxLines: 3,
-            ),
-          ],
+              const SizedBox(height: 12),
+              TextFormField(
+                controller: controller.catatanController,
+                decoration: const InputDecoration(
+                  labelText: 'Catatan (opsional)',
+                  border: OutlineInputBorder(),
+                ),
+                maxLines: 2,
+              ),
+            ],
+          ),
         ),
         actions: [
           TextButton(
@@ -582,15 +593,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
           ),
           ElevatedButton(
             onPressed: () {
-              // Implementasi untuk menyimpan tindakan
-              Navigator.pop(context);
-              Get.snackbar(
-                'Berhasil',
-                'Status pengaduan berhasil diubah menjadi Tindakan',
-                snackPosition: SnackPosition.TOP,
-                backgroundColor: Colors.blue,
-                colorText: Colors.white,
-              );
+              controller.tambahTindakan(item.id!);
             },
             child: const Text('Simpan'),
           ),
@@ -599,9 +602,7 @@ class PengaduanView extends GetView<PetugasDesaController> {
     );
   }
 
-  void _showSelesaikanDialog(BuildContext context, Map<String, dynamic> item) {
-    final TextEditingController hasilController = TextEditingController();
-
+  void _showSelesaikanDialog(BuildContext context, dynamic item) {
     showDialog(
       context: context,
       builder: (context) => AlertDialog(
@@ -609,15 +610,11 @@ class PengaduanView extends GetView<PetugasDesaController> {
         content: Column(
           mainAxisSize: MainAxisSize.min,
           children: [
-            Text('Pengaduan dari: ${item['nama']}'),
+            Text('Pengaduan dari: ${item.warga?['nama'] ?? ''}'),
             const SizedBox(height: 16),
-            TextField(
-              controller: hasilController,
-              decoration: const InputDecoration(
-                labelText: 'Hasil penyelesaian',
-                border: OutlineInputBorder(),
-              ),
-              maxLines: 3,
+            const Text(
+              'Apakah Anda yakin ingin menyelesaikan pengaduan ini?',
+              textAlign: TextAlign.center,
             ),
           ],
         ),
@@ -628,15 +625,8 @@ class PengaduanView extends GetView<PetugasDesaController> {
           ),
           ElevatedButton(
             onPressed: () {
-              // Implementasi untuk menyimpan hasil
               Navigator.pop(context);
-              Get.snackbar(
-                'Berhasil',
-                'Status pengaduan berhasil diubah menjadi Selesai',
-                snackPosition: SnackPosition.TOP,
-                backgroundColor: Colors.green,
-                colorText: Colors.white,
-              );
+              controller.selesaikanPengaduan(item.id!);
             },
             child: const Text('Selesaikan'),
           ),
diff --git a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
index 461cecb..c850e90 100644
--- a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
+++ b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
@@ -273,11 +273,15 @@ class WargaDashboardController extends GetxController {
   // Fungsi untuk mengambil data pengaduan
   Future<void> fetchPengaduan() async {
     try {
-      final response = await _supabaseService.client
-          .from('pengaduan')
-          .select('*')
-          .eq('pelapor', user!.id)
-          .order('created_at', ascending: false);
+      final wargaData = await _supabaseService.getWargaByUserId();
+      if (wargaData == null) {
+        print('Data warga tidak ditemukan');
+        return;
+      }
+
+      final String wargaId = wargaData['id'];
+      final response = await _supabaseService
+          .getPengaduanWargaWithPenerimaPenyaluran(wargaId);
 
       if (response != null) {
         final List<PengaduanModel> pengaduanList = [];
@@ -289,7 +293,7 @@ class WargaDashboardController extends GetxController {
         // Hitung jumlah berdasarkan status
         totalPengaduan.value = pengaduanList.length;
         totalPengaduanProses.value = pengaduanList
-            .where((p) => p.status == 'PROSES' || p.status == 'DIPROSES')
+            .where((p) => p.status == 'MENUNGGU' || p.status == 'TINDAKAN')
             .length;
         totalPengaduanSelesai.value =
             pengaduanList.where((p) => p.status == 'SELESAI').length;
@@ -342,4 +346,39 @@ class WargaDashboardController extends GetxController {
   void logout() {
     _authController.logout();
   }
+
+  Future<Map<String, dynamic>> getDetailPengaduan(String pengaduanId) async {
+    try {
+      // Ambil data pengaduan
+      final pengaduanData =
+          await _supabaseService.client.from('pengaduan').select('''
+            *,
+            penerima_penyaluran:penerima_penyaluran_id(
+              *,
+              penyaluran_bantuan:penyaluran_bantuan_id(*),
+              stok_bantuan:stok_bantuan_id(*),
+              warga:warga_id(*)
+            ),
+            warga:warga_id(*)
+          ''').eq('id', pengaduanId).single();
+
+      // Ambil data tindakan pengaduan
+      final tindakanData =
+          await _supabaseService.getTindakanPengaduan(pengaduanId);
+
+      // Gabungkan data
+      final result = {
+        'pengaduan': pengaduanData,
+        'tindakan': tindakanData ?? [],
+      };
+
+      return result;
+    } catch (e) {
+      print('Error getting detail pengaduan: $e');
+      return {
+        'pengaduan': null,
+        'tindakan': [],
+      };
+    }
+  }
 }
diff --git a/lib/app/modules/warga/views/detail_pengaduan_view.dart b/lib/app/modules/warga/views/detail_pengaduan_view.dart
new file mode 100644
index 0000000..fe145a2
--- /dev/null
+++ b/lib/app/modules/warga/views/detail_pengaduan_view.dart
@@ -0,0 +1,449 @@
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:intl/intl.dart';
+import 'package:penyaluran_app/app/data/models/pengaduan_model.dart';
+import 'package:penyaluran_app/app/data/models/tindakan_pengaduan_model.dart';
+import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
+import 'package:penyaluran_app/app/theme/app_theme.dart';
+import 'package:timeline_tile/timeline_tile.dart';
+
+class WargaDetailPengaduanView extends GetView<WargaDashboardController> {
+  const WargaDetailPengaduanView({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final Map<String, dynamic> args = Get.arguments ?? {};
+    final String pengaduanId = args['id'] ?? '';
+
+    if (pengaduanId.isEmpty) {
+      return Scaffold(
+        appBar: AppBar(
+          title: const Text('Detail Pengaduan'),
+        ),
+        body: const Center(
+          child: Text('ID Pengaduan tidak valid'),
+        ),
+      );
+    }
+
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Detail Pengaduan'),
+        elevation: 0,
+      ),
+      body: FutureBuilder<Map<String, dynamic>>(
+        future: controller.getDetailPengaduan(pengaduanId),
+        builder: (context, snapshot) {
+          if (snapshot.connectionState == ConnectionState.waiting) {
+            return const Center(child: CircularProgressIndicator());
+          }
+
+          if (snapshot.hasError) {
+            return Center(
+              child: Text('Error: ${snapshot.error}'),
+            );
+          }
+
+          final data = snapshot.data;
+          if (data == null || data['pengaduan'] == null) {
+            return const Center(
+              child: Text('Data pengaduan tidak ditemukan'),
+            );
+          }
+
+          final pengaduan = PengaduanModel.fromJson(data['pengaduan']);
+          final List<TindakanPengaduanModel> tindakanList =
+              (data['tindakan'] as List)
+                  .map((item) => TindakanPengaduanModel.fromJson(item))
+                  .toList();
+
+          return _buildDetailContent(context, pengaduan, tindakanList);
+        },
+      ),
+    );
+  }
+
+  Widget _buildDetailContent(
+    BuildContext context,
+    PengaduanModel pengaduan,
+    List<TindakanPengaduanModel> tindakanList,
+  ) {
+    // Tentukan status dan warna
+    Color statusColor;
+    String statusText;
+
+    switch (pengaduan.status?.toUpperCase()) {
+      case 'MENUNGGU':
+        statusColor = Colors.orange;
+        statusText = 'Menunggu';
+        break;
+      case 'TINDAKAN':
+        statusColor = Colors.blue;
+        statusText = 'Tindakan';
+        break;
+      case 'SELESAI':
+        statusColor = Colors.green;
+        statusText = 'Selesai';
+        break;
+      default:
+        statusColor = Colors.grey;
+        statusText = pengaduan.status ?? 'Tidak Diketahui';
+    }
+
+    return SingleChildScrollView(
+      padding: const EdgeInsets.all(16),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          // Header dengan status
+          _buildHeaderWithStatus(context, pengaduan, statusColor, statusText),
+
+          const SizedBox(height: 24),
+
+          // Informasi penyaluran yang diadukan
+          if (pengaduan.penerimaPenyaluran != null)
+            _buildPenyaluranInfo(context, pengaduan),
+
+          const SizedBox(height: 24),
+
+          // Timeline tindakan
+          _buildTindakanTimeline(context, tindakanList),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildHeaderWithStatus(
+    BuildContext context,
+    PengaduanModel pengaduan,
+    Color statusColor,
+    String statusText,
+  ) {
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Expanded(
+                  child: Text(
+                    pengaduan.judul ?? 'Pengaduan',
+                    style: const TextStyle(
+                      fontSize: 20,
+                      fontWeight: FontWeight.bold,
+                    ),
+                  ),
+                ),
+                Container(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 12,
+                    vertical: 6,
+                  ),
+                  decoration: BoxDecoration(
+                    color: statusColor.withOpacity(0.1),
+                    borderRadius: BorderRadius.circular(20),
+                    border: Border.all(
+                      color: statusColor,
+                    ),
+                  ),
+                  child: Text(
+                    statusText,
+                    style: TextStyle(
+                      color: statusColor,
+                      fontWeight: FontWeight.bold,
+                      fontSize: 12,
+                    ),
+                  ),
+                ),
+              ],
+            ),
+            const SizedBox(height: 12),
+            Text(
+              pengaduan.deskripsi ?? '',
+              style: TextStyle(
+                fontSize: 14,
+                color: Colors.grey.shade700,
+              ),
+            ),
+            const SizedBox(height: 12),
+            Row(
+              children: [
+                Icon(
+                  Icons.calendar_today,
+                  size: 16,
+                  color: Colors.grey.shade600,
+                ),
+                const SizedBox(width: 8),
+                Text(
+                  pengaduan.tanggalPengaduan != null
+                      ? DateFormat('dd MMMM yyyy', 'id_ID')
+                          .format(pengaduan.tanggalPengaduan!)
+                      : '-',
+                  style: TextStyle(
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildPenyaluranInfo(BuildContext context, PengaduanModel pengaduan) {
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const Text(
+              'Informasi Penyaluran',
+              style: TextStyle(
+                fontSize: 16,
+                fontWeight: FontWeight.bold,
+              ),
+            ),
+            const SizedBox(height: 16),
+            _buildInfoRow('Nama Penyaluran', pengaduan.namaPenyaluran),
+            _buildInfoRow('Jenis Bantuan', pengaduan.jenisBantuan),
+            _buildInfoRow('Jumlah Bantuan', pengaduan.jumlahBantuan),
+            _buildInfoRow('Deskripsi', pengaduan.deskripsiPenyaluran),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildTindakanTimeline(
+    BuildContext context,
+    List<TindakanPengaduanModel> tindakanList,
+  ) {
+    if (tindakanList.isEmpty) {
+      return Card(
+        elevation: 2,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(12),
+        ),
+        child: const Padding(
+          padding: EdgeInsets.all(16),
+          child: Center(
+            child: Text(
+              'Pengaduan Anda sedang menunggu tindakan dari petugas',
+              style: TextStyle(
+                fontSize: 14,
+                fontStyle: FontStyle.italic,
+                color: Colors.grey,
+              ),
+            ),
+          ),
+        ),
+      );
+    }
+
+    return Card(
+      elevation: 2,
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(12),
+      ),
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const Text(
+              'Riwayat Tindakan',
+              style: TextStyle(
+                fontSize: 16,
+                fontWeight: FontWeight.bold,
+              ),
+            ),
+            const SizedBox(height: 16),
+            ListView.builder(
+              shrinkWrap: true,
+              physics: const NeverScrollableScrollPhysics(),
+              itemCount: tindakanList.length,
+              itemBuilder: (context, index) {
+                final tindakan = tindakanList[index];
+                final bool isFirst = index == 0;
+                final bool isLast = index == tindakanList.length - 1;
+
+                return _buildTimelineTile(
+                  context,
+                  tindakan,
+                  isFirst,
+                  isLast,
+                );
+              },
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildTimelineTile(
+    BuildContext context,
+    TindakanPengaduanModel tindakan,
+    bool isFirst,
+    bool isLast,
+  ) {
+    Color dotColor;
+    switch (tindakan.statusTindakan) {
+      case 'SELESAI':
+        dotColor = Colors.green;
+        break;
+      case 'PROSES':
+        dotColor = Colors.blue;
+        break;
+      default:
+        dotColor = Colors.grey;
+    }
+
+    return TimelineTile(
+      alignment: TimelineAlign.start,
+      isFirst: isFirst,
+      isLast: isLast,
+      indicatorStyle: IndicatorStyle(
+        width: 20,
+        color: dotColor,
+        iconStyle: IconStyle(
+          color: Colors.white,
+          iconData:
+              tindakan.statusTindakan == 'SELESAI' ? Icons.check : Icons.sync,
+        ),
+      ),
+      endChild: Container(
+        margin: const EdgeInsets.only(left: 16, bottom: 24),
+        padding: const EdgeInsets.all(16),
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.circular(8),
+          boxShadow: [
+            BoxShadow(
+              color: Colors.grey.withOpacity(0.1),
+              spreadRadius: 1,
+              blurRadius: 2,
+              offset: const Offset(0, 1),
+            ),
+          ],
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Text(
+                  tindakan.kategoriTindakanText,
+                  style: const TextStyle(
+                    fontWeight: FontWeight.bold,
+                    fontSize: 16,
+                  ),
+                ),
+                Container(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 8,
+                    vertical: 4,
+                  ),
+                  decoration: BoxDecoration(
+                    color: dotColor.withOpacity(0.1),
+                    borderRadius: BorderRadius.circular(4),
+                  ),
+                  child: Text(
+                    tindakan.statusTindakanText,
+                    style: TextStyle(
+                      color: dotColor,
+                      fontSize: 12,
+                      fontWeight: FontWeight.bold,
+                    ),
+                  ),
+                ),
+              ],
+            ),
+            const SizedBox(height: 8),
+            Text(
+              tindakan.tindakan ?? '',
+              style: const TextStyle(fontSize: 14),
+            ),
+            if (tindakan.hasilTindakan != null &&
+                tindakan.hasilTindakan!.isNotEmpty) ...[
+              const SizedBox(height: 8),
+              Text(
+                'Hasil: ${tindakan.hasilTindakan}',
+                style: TextStyle(
+                  fontSize: 12,
+                  color: Colors.grey.shade700,
+                ),
+              ),
+            ],
+            const SizedBox(height: 8),
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Text(
+                  'Oleh: ${tindakan.namaPetugas}',
+                  style: TextStyle(
+                    fontSize: 12,
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+                Text(
+                  tindakan.tanggalTindakan != null
+                      ? DateFormat('dd MMM yyyy', 'id_ID')
+                          .format(tindakan.tanggalTindakan!)
+                      : '-',
+                  style: TextStyle(
+                    fontSize: 12,
+                    color: Colors.grey.shade600,
+                  ),
+                ),
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildInfoRow(String label, String value) {
+    return Padding(
+      padding: const EdgeInsets.only(bottom: 8),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          SizedBox(
+            width: 120,
+            child: Text(
+              '$label:',
+              style: TextStyle(
+                fontWeight: FontWeight.w500,
+                color: Colors.grey.shade700,
+              ),
+            ),
+          ),
+          Expanded(
+            child: Text(
+              value,
+              style: const TextStyle(
+                color: Colors.black87,
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/app/modules/warga/views/warga_dashboard_view.dart b/lib/app/modules/warga/views/warga_dashboard_view.dart
index cac0103..33a3fdf 100644
--- a/lib/app/modules/warga/views/warga_dashboard_view.dart
+++ b/lib/app/modules/warga/views/warga_dashboard_view.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:intl/intl.dart';
 import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
+import 'package:penyaluran_app/app/routes/app_pages.dart';
 import 'package:penyaluran_app/app/widgets/bantuan_card.dart';
 import 'package:penyaluran_app/app/widgets/section_header.dart';
 
@@ -290,10 +291,9 @@ class WargaDashboardView extends GetView<WargaDashboardController> {
           title: 'Bantuan Terbaru',
           viewAllText: 'Lihat Semua',
           onViewAll: () {
-            Get.toNamed('/warga-penerimaan');
+            Get.toNamed(Routes.wargaPenerimaan);
           },
         ),
-        const SizedBox(height: 16),
         ListView.builder(
           shrinkWrap: true,
           physics: const NeverScrollableScrollPhysics(),
diff --git a/lib/app/modules/warga/views/warga_pengaduan_view.dart b/lib/app/modules/warga/views/warga_pengaduan_view.dart
index 73fca8e..ec4d7a8 100644
--- a/lib/app/modules/warga/views/warga_pengaduan_view.dart
+++ b/lib/app/modules/warga/views/warga_pengaduan_view.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:intl/intl.dart';
 import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
+import 'package:penyaluran_app/app/utils/date_time_helper.dart';
 
 class WargaPengaduanView extends GetView<WargaDashboardController> {
   const WargaPengaduanView({Key? key}) : super(key: key);
@@ -83,11 +84,13 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
         String statusText;
 
         switch (item.status?.toUpperCase()) {
-          case 'PROSES':
-          case 'DIPROSES':
-          case 'TINDAKAN':
+          case 'MENUNGGU':
             statusColor = Colors.orange;
-            statusText = 'Proses';
+            statusText = 'Menunggu';
+            break;
+          case 'TINDAKAN':
+            statusColor = Colors.blue;
+            statusText = 'Tindakan';
             break;
           case 'SELESAI':
             statusColor = Colors.green;
@@ -102,8 +105,6 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
             statusText = item.status ?? 'Tidak Diketahui';
         }
 
-        final isProses = statusText == 'Proses';
-
         return Card(
           margin: const EdgeInsets.only(bottom: 16),
           shape: RoundedRectangleBorder(
@@ -112,7 +113,9 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
           elevation: 2,
           child: InkWell(
             onTap: () {
-              // TODO: Navigasi ke detail pengaduan
+              // Navigasi ke detail pengaduan
+              Get.toNamed('/warga/detail-pengaduan',
+                  arguments: {'id': item.id});
             },
             borderRadius: BorderRadius.circular(12),
             child: Padding(
@@ -158,6 +161,52 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
                     ],
                   ),
                   const SizedBox(height: 12),
+
+                  // Informasi penyaluran bantuan
+                  if (item.penerimaPenyaluran != null)
+                    Container(
+                      padding: const EdgeInsets.all(8),
+                      margin: const EdgeInsets.only(bottom: 12),
+                      decoration: BoxDecoration(
+                        color: Colors.blue.shade50,
+                        borderRadius: BorderRadius.circular(8),
+                      ),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          Text(
+                            'Penyaluran: ${item.namaPenyaluran}',
+                            style: const TextStyle(
+                              fontWeight: FontWeight.bold,
+                            ),
+                          ),
+                          const SizedBox(height: 4),
+                          Row(
+                            children: [
+                              Expanded(
+                                child: Text(
+                                  'Jenis: ${item.jenisBantuan}',
+                                  style: TextStyle(
+                                    fontSize: 12,
+                                    color: Colors.grey.shade700,
+                                  ),
+                                ),
+                              ),
+                              Expanded(
+                                child: Text(
+                                  'Jumlah: ${item.jumlahBantuan}',
+                                  style: TextStyle(
+                                    fontSize: 12,
+                                    color: Colors.grey.shade700,
+                                  ),
+                                ),
+                              ),
+                            ],
+                          ),
+                        ],
+                      ),
+                    ),
+
                   if (item.deskripsi != null && item.deskripsi!.isNotEmpty)
                     Padding(
                       padding: const EdgeInsets.only(bottom: 12),
@@ -180,8 +229,8 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
                       const SizedBox(width: 8),
                       Text(
                         item.tanggalPengaduan != null
-                            ? DateFormat('dd MMMM yyyy', 'id_ID')
-                                .format(item.tanggalPengaduan!)
+                            ? DateTimeHelper.formatDateTime(
+                                item.tanggalPengaduan!)
                             : '-',
                         style: TextStyle(
                           color: Colors.grey.shade600,
@@ -197,8 +246,8 @@ class WargaPengaduanView extends GetView<WargaDashboardController> {
                     children: [
                       TextButton.icon(
                         onPressed: () {
-                          // TODO: Implementasi navigasi ke detail pengaduan
-                          Get.toNamed('/detail-pengaduan',
+                          // Navigasi ke detail pengaduan
+                          Get.toNamed('/warga/detail-pengaduan',
                               arguments: {'id': item.id});
                         },
                         icon: const Icon(Icons.visibility),
diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart
index b0c3b4b..a05ecea 100644
--- a/lib/app/routes/app_pages.dart
+++ b/lib/app/routes/app_pages.dart
@@ -27,6 +27,9 @@ import 'package:penyaluran_app/app/modules/warga/views/warga_pengaduan_view.dart
 import 'package:penyaluran_app/app/modules/warga/views/warga_view.dart';
 import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
 import 'package:penyaluran_app/app/modules/warga/views/warga_detail_penerimaan_view.dart';
+import 'package:penyaluran_app/app/modules/petugas_desa/views/detail_pengaduan_view.dart';
+import 'package:penyaluran_app/app/modules/petugas_desa/bindings/pengaduan_binding.dart';
+import 'package:penyaluran_app/app/modules/warga/views/detail_pengaduan_view.dart';
 
 part 'app_routes.dart';
 
@@ -124,10 +127,20 @@ class AppPages {
       page: () => DetailPenyaluranPage(),
       binding: PenyaluranBinding(),
     ),
+    GetPage(
+      name: _Paths.detailPengaduan,
+      page: () => const DetailPengaduanView(),
+      binding: PengaduanBinding(),
+    ),
     GetPage(
       name: Routes.wargaDetailPenerimaan,
       page: () => const WargaDetailPenerimaanView(),
       binding: WargaBinding(),
     ),
+    GetPage(
+      name: Routes.wargaDetailPengaduan,
+      page: () => const WargaDetailPengaduanView(),
+      binding: WargaBinding(),
+    ),
   ];
 }
diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart
index b521c92..e71ee22 100644
--- a/lib/app/routes/app_routes.dart
+++ b/lib/app/routes/app_routes.dart
@@ -28,6 +28,8 @@ abstract class Routes {
   static const detailPenyaluran = _Paths.detailPenyaluran;
   static const riwayatPenyaluran = _Paths.riwayatPenyaluran;
   static const wargaDetailPenerimaan = _Paths.wargaDetailPenerimaan;
+  static const detailPengaduan = _Paths.detailPengaduan;
+  static const wargaDetailPengaduan = _Paths.wargaDetailPengaduan;
 }
 
 abstract class _Paths {
@@ -58,4 +60,6 @@ abstract class _Paths {
   static const detailPenyaluran = '/detail-penyaluran';
   static const riwayatPenyaluran = '/petugas-desa/riwayat-penyaluran';
   static const wargaDetailPenerimaan = '/warga/detail-penerimaan';
+  static const detailPengaduan = '/detail-pengaduan';
+  static const wargaDetailPengaduan = '/warga/detail-pengaduan';
 }
diff --git a/lib/app/services/supabase_service.dart b/lib/app/services/supabase_service.dart
index 13735fc..b93a249 100644
--- a/lib/app/services/supabase_service.dart
+++ b/lib/app/services/supabase_service.dart
@@ -701,6 +701,50 @@ class SupabaseService extends GetxService {
     }
   }
 
+  // Metode untuk mendapatkan pengaduan dengan detail penerima penyaluran
+  Future<List<Map<String, dynamic>>?>
+      getPengaduanWithPenerimaPenyaluran() async {
+    try {
+      final response = await client.from('pengaduan').select('''
+            *,
+            penerima_penyaluran:penerima_penyaluran_id(
+              *,
+              penyaluran_bantuan:penyaluran_bantuan_id(*),
+              stok_bantuan:stok_bantuan_id(*),
+              warga:warga_id(*)
+            ),
+            warga:warga_id(*)
+          ''').order('created_at', ascending: false);
+
+      return response;
+    } catch (e) {
+      print('Error getting pengaduan with penerima penyaluran: $e');
+      return null;
+    }
+  }
+
+  // Metode untuk mendapatkan pengaduan warga tertentu dengan detail penerima penyaluran
+  Future<List<Map<String, dynamic>>?> getPengaduanWargaWithPenerimaPenyaluran(
+      String wargaId) async {
+    try {
+      final response = await client.from('pengaduan').select('''
+            *,
+            penerima_penyaluran:penerima_penyaluran_id(
+              *,
+              penyaluran_bantuan:penyaluran_bantuan_id(*),
+              stok_bantuan:stok_bantuan_id(*),
+              warga:warga_id(*)
+            ),
+            warga:warga_id(*)
+          ''').eq('warga_id', wargaId).order('created_at', ascending: false);
+
+      return response;
+    } catch (e) {
+      print('Error getting warga pengaduan with penerima penyaluran: $e');
+      return null;
+    }
+  }
+
   Future<void> prosesPengaduan(String pengaduanId) async {
     try {
       await client.from('pengaduan').update({
@@ -722,6 +766,19 @@ class SupabaseService extends GetxService {
     }
   }
 
+  Future<void> updateTindakanPengaduan(
+      String tindakanId, Map<String, dynamic> tindakan) async {
+    try {
+      await client
+          .from('tindakan_pengaduan')
+          .update(tindakan)
+          .eq('id', tindakanId);
+    } catch (e) {
+      print('Error updating tindakan pengaduan: $e');
+      throw e.toString();
+    }
+  }
+
   Future<void> updateStatusPengaduan(String pengaduanId, String status) async {
     try {
       await client.from('pengaduan').update({
@@ -739,7 +796,11 @@ class SupabaseService extends GetxService {
     try {
       final response = await client
           .from('tindakan_pengaduan')
-          .select('*')
+          .select('''
+            *,
+            petugas:petugas_id(id, nama, email),
+            verifikator:verifikator_id(id, nama, email)
+          ''')
           .eq('pengaduan_id', pengaduanId)
           .order('created_at', ascending: false);
 
diff --git a/lib/app/widgets/section_header.dart b/lib/app/widgets/section_header.dart
index df89541..927aafd 100644
--- a/lib/app/widgets/section_header.dart
+++ b/lib/app/widgets/section_header.dart
@@ -14,7 +14,7 @@ class SectionHeader extends StatelessWidget {
     this.onViewAll,
     this.viewAllText = 'Lihat Semua',
     this.trailing,
-    this.padding = const EdgeInsets.only(bottom: 12),
+    this.padding = const EdgeInsets.only(bottom: 4),
     this.titleStyle,
   }) : super(key: key);
 
diff --git a/pubspec.lock b/pubspec.lock
index 3c8a7c5..675ae16 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -834,6 +834,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.7.4"
+  timeline_tile:
+    dependency: "direct main"
+    description:
+      name: timeline_tile
+      sha256: "85ec2023c67137397c2812e3e848b2fb20b410b67cd9aff304bb5480c376fc0c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.0"
   timezone:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index bd83019..5c26ce8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -70,6 +70,7 @@ dependencies:
   flutter_localizations:
     sdk: flutter
   flutter_staggered_animations: ^1.1.1
+  timeline_tile: ^2.0.0
 
 dev_dependencies:
   flutter_test:
