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 44c7df9..b8cb640 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 37946ec..093da6a 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 c805443..bc005df 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 abe166b..4d1087f 100644
--- a/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin
+++ b/android/app/.cxx/Debug/626b5o2n/x86_64/configure_fingerprint.bin
@@ -2,27 +2,27 @@ C/C++ Structured LogO
 M
 KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
 A
-?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint	Ü¯ÙƒÛ2§ šôÔÍÙ2~
+?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint	»ûæÚÜ2§ šôÔÍÙ2~
 |
-zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt	Ü¯ÙƒÛ2 ÆóÕÐÙ2{
+zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt	¼ûæÚÜ2 ÆóÕÐÙ2{
 y
-wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json	Ü¯ÙƒÛ2á ÔóÕÐÙ2€
+wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json	¼ûæÚÜ2á ÔóÕÐÙ2€
 ~
-|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json	Ü¯ÙƒÛ2¸ éóÕÐÙ2m
+|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json	¼ûæÚÜ2¸ éóÕÐÙ2m
 k
-iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja	Ý¯ÙƒÛ2�Ø ùïÕÐÙ2q
+iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja	¼ûæÚÜ2�Ø ùïÕÐÙ2q
 o
-mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt	Ý¯ÙƒÛ2v
+mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt	¼ûæÚÜ2v
 t
-rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt	Ý¯ÙƒÛ2
K ëóÕÐÙ2w
+rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt	¼ûæÚÜ2
K ëóÕÐÙ2w
 u
-sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json	Ý¯ÙƒÛ2	{
+sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json	¼ûæÚÜ2	{
 y
-wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin	Ý¯ÙƒÛ2
+wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin	¼ûæÚÜ2
 �
 
-}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt	Ý¯ÙƒÛ2þ êóÕÐÙ2t
+}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt	¼ûæÚÜ2þ êóÕÐÙ2t
 r
-pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json	Ý¯ÙƒÛ2
( êóÕÐÙ2y
+pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json	¼ûæÚÜ2
( êóÕÐÙ2y
 w
-uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\symbol_folder_index.txt	Þ¯ÙƒÛ2

l ëóÕÐÙ2
\ No newline at end of file
+uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\symbol_folder_index.txt	¼ûæÚÜ2

l ëóÕÐÙ2
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index db77bb4..56d485a 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 17987b7..804e91b 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 09d4391..802249c 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index d5f1c8d..a7bbc6e 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 4d6372e..7c50f36 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/assets/images/penyaluran-icon.png b/assets/images/penyaluran-icon.png
new file mode 100644
index 0000000..0e1f911
Binary files /dev/null and b/assets/images/penyaluran-icon.png differ
diff --git a/lib/app/data/models/donatur_model.dart b/lib/app/data/models/donatur_model.dart
index 51ab672..939b5f0 100644
--- a/lib/app/data/models/donatur_model.dart
+++ b/lib/app/data/models/donatur_model.dart
@@ -1,24 +1,26 @@
 import 'dart:convert';
 
 class DonaturModel {
-  final String? id;
-  final String? nama;
+  final String id; // Primary key yang juga foreign key ke auth.users(id)
+  final String? namaLengkap;
   final String? alamat;
-  final String? telepon;
+  final String? noHp;
   final String? email;
   final String? jenis;
+  final String? deskripsi;
   final String? status;
   final DateTime? createdAt;
   final DateTime? updatedAt;
 
   DonaturModel({
-    this.id,
-    this.nama,
+    required this.id,
+    this.namaLengkap,
     this.alamat,
-    this.telepon,
+    this.noHp,
     this.email,
     this.jenis,
-    this.status,
+    this.deskripsi,
+    this.status = 'AKTIF',
     this.createdAt,
     this.updatedAt,
   });
@@ -30,11 +32,12 @@ class DonaturModel {
 
   factory DonaturModel.fromJson(Map<String, dynamic> json) => DonaturModel(
         id: json["id"],
-        nama: json["nama"],
+        namaLengkap: json["nama_lengkap"],
         alamat: json["alamat"],
-        telepon: json["telepon"],
+        noHp: json["no_hp"],
         email: json["email"],
         jenis: json["jenis"],
+        deskripsi: json["deskripsi"],
         status: json["status"] ?? 'AKTIF',
         createdAt: json["created_at"] != null
             ? DateTime.parse(json["created_at"])
@@ -46,13 +49,20 @@ class DonaturModel {
 
   Map<String, dynamic> toJson() => {
         "id": id,
-        "nama": nama,
+        "nama_lengkap": namaLengkap,
         "alamat": alamat,
-        "telepon": telepon,
+        "no_hp": noHp,
         "email": email,
         "jenis": jenis,
+        "deskripsi": deskripsi,
         "status": status ?? 'AKTIF',
         "created_at": createdAt?.toIso8601String(),
         "updated_at": updatedAt?.toIso8601String(),
       };
+
+  // Helper method untuk mendapatkan nama yang ditampilkan
+  String get displayName => namaLengkap ?? 'Donatur';
+
+  // Getter untuk kompatibilitas dengan kode yang masih menggunakan nama
+  String? get nama => namaLengkap;
 }
diff --git a/lib/app/data/models/petugas_desa_model.dart b/lib/app/data/models/petugas_desa_model.dart
index 8d90b9e..9a8fd10 100644
--- a/lib/app/data/models/petugas_desa_model.dart
+++ b/lib/app/data/models/petugas_desa_model.dart
@@ -1,26 +1,31 @@
 import 'dart:convert';
+import 'package:penyaluran_app/app/data/models/desa_model.dart';
 
 class PetugasDesaModel {
-  final String? id;
-  final String? nama;
-  final String? alamatLengkap;
-  final String? noTelp;
+  final String id; // Primary key yang juga foreign key ke auth.users(id)
+  final String? desaId;
+  final String? namaLengkap;
+  final String? alamat;
+  final String? noHp;
   final String? email;
   final String? jabatan;
-  final String? userId;
+  final String? nip;
   final DateTime? createdAt;
   final DateTime? updatedAt;
+  final DesaModel? desa;
 
   PetugasDesaModel({
-    this.id,
-    this.nama,
-    this.alamatLengkap,
-    this.noTelp,
+    required this.id,
+    this.desaId,
+    this.namaLengkap,
+    this.alamat,
+    this.noHp,
     this.email,
     this.jabatan,
-    this.userId,
+    this.nip,
     this.createdAt,
     this.updatedAt,
+    this.desa,
   });
 
   factory PetugasDesaModel.fromRawJson(String str) =>
@@ -28,32 +33,44 @@ class PetugasDesaModel {
 
   String toRawJson() => json.encode(toJson());
 
-  factory PetugasDesaModel.fromJson(Map<String, dynamic> json) =>
-      PetugasDesaModel(
-        id: json["id"],
-        nama: json["nama"],
-        alamatLengkap: json["alamat_lengkap"],
-        noTelp: json["no_telp"],
-        email: json["email"],
-        jabatan: json["jabatan"],
-        userId: json["user_id"],
-        createdAt: json["created_at"] != null
-            ? DateTime.parse(json["created_at"])
-            : null,
-        updatedAt: json["updated_at"] != null
-            ? DateTime.parse(json["updated_at"])
-            : null,
-      );
+  factory PetugasDesaModel.fromJson(Map<String, dynamic> json) {
+    DesaModel? desa;
+    if (json["desa"] != null && json["desa"] is Map<String, dynamic>) {
+      desa = DesaModel.fromJson(json["desa"]);
+    }
+
+    return PetugasDesaModel(
+      id: json["id"],
+      desaId: json["desa_id"],
+      namaLengkap: json["nama_lengkap"],
+      alamat: json["alamat"],
+      noHp: json["no_hp"],
+      email: json["email"],
+      jabatan: json["jabatan"],
+      nip: json["nip"],
+      createdAt: json["created_at"] != null
+          ? DateTime.parse(json["created_at"])
+          : null,
+      updatedAt: json["updated_at"] != null
+          ? DateTime.parse(json["updated_at"])
+          : null,
+      desa: desa,
+    );
+  }
 
   Map<String, dynamic> toJson() => {
         "id": id,
-        "nama": nama,
-        "alamat_lengkap": alamatLengkap,
-        "no_telp": noTelp,
+        "desa_id": desaId,
+        "nama_lengkap": namaLengkap,
+        "alamat": alamat,
+        "no_hp": noHp,
         "email": email,
         "jabatan": jabatan,
-        "user_id": userId,
+        "nip": nip,
         "created_at": createdAt?.toIso8601String(),
         "updated_at": updatedAt?.toIso8601String(),
       };
+
+  // Helper method untuk mendapatkan nama yang ditampilkan
+  String get displayName => namaLengkap ?? 'Petugas Desa';
 }
diff --git a/lib/app/data/models/tindakan_pengaduan_model.dart b/lib/app/data/models/tindakan_pengaduan_model.dart
index c793516..2549b5a 100644
--- a/lib/app/data/models/tindakan_pengaduan_model.dart
+++ b/lib/app/data/models/tindakan_pengaduan_model.dart
@@ -101,20 +101,16 @@ class TindakanPengaduanModel {
 
   // 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'];
+    if (petugas != null && petugas!['nama_lengkap'] != null) {
+      return petugas!['nama_lengkap'];
     }
     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'];
+    if (verifikator != null && verifikator!['nama_lengkap'] != null) {
+      return verifikator!['nama_lengkap'];
     }
     return 'Belum diverifikasi';
   }
diff --git a/lib/app/data/models/user_model.dart b/lib/app/data/models/user_model.dart
index 062e157..ac5926e 100644
--- a/lib/app/data/models/user_model.dart
+++ b/lib/app/data/models/user_model.dart
@@ -1,51 +1,58 @@
 import 'package:penyaluran_app/app/data/models/desa_model.dart';
 
-class UserModel {
+// Model dasar untuk pengguna dengan informasi autentikasi umum
+class BaseUserModel {
   final String id;
   final String email;
-  final String? name;
-  final String? avatar;
-  final String role;
+  final int? roleId;
+  final String roleName;
   final bool isActive;
-  final DesaModel? desa;
-  final String? desaId;
   final DateTime? lastLogin;
   final DateTime? createdAt;
   final DateTime? updatedAt;
+  final String? name;
+  final String? role;
+  final DesaModel? desa;
 
-  UserModel({
+  BaseUserModel({
     required this.id,
     required this.email,
-    this.name,
-    this.avatar,
-    required this.role,
+    this.roleId,
+    required this.roleName,
     this.isActive = true,
-    this.desa,
-    this.desaId,
     this.lastLogin,
     this.createdAt,
     this.updatedAt,
+    this.name,
+    this.role,
+    this.desa,
   });
 
-  factory UserModel.fromJson(Map<String, dynamic> json) {
+  factory BaseUserModel.fromJson(Map<String, dynamic> json) {
+    // Pastikan id dan email tidak null
     if (json['id'] == null || json['email'] == null) {
-      throw Exception('UserModel: id dan email tidak boleh null');
+      throw Exception('BaseUserModel: id dan email tidak boleh null');
     }
 
-    // Parse desa jika ada
-    DesaModel? desaModel;
+    // Dapatkan roleName, default ke 'warga' jika tidak tersedia
+    String roleName = 'warga';
+    if (json['roles'] != null && json['roles']['role_name'] != null) {
+      roleName = json['roles']['role_name'];
+    } else if (json['role'] != null) {
+      roleName = json['role'];
+    }
+
+    // Parse desa data jika ada
+    DesaModel? desa;
     if (json['desa'] != null && json['desa'] is Map<String, dynamic>) {
-      desaModel = DesaModel.fromJson(json['desa'] as Map<String, dynamic>);
+      desa = DesaModel.fromJson(json['desa']);
     }
 
-    return UserModel(
+    return BaseUserModel(
       id: json['id'],
       email: json['email'],
-      name: json['name'],
-      avatar: json['avatar'],
-      desa: desaModel,
-      desaId: json['desa_id'],
-      role: json['role'] ?? 'WARGA',
+      roleId: json['role_id'],
+      roleName: roleName,
       isActive: json['is_active'] ?? true,
       lastLogin: json['last_login'] != null
           ? DateTime.parse(json['last_login'])
@@ -56,6 +63,9 @@ class UserModel {
       updatedAt: json['updated_at'] != null
           ? DateTime.parse(json['updated_at'])
           : null,
+      name: json['name'],
+      role: roleName,
+      desa: desa,
     );
   }
 
@@ -63,83 +73,25 @@ class UserModel {
     return {
       'id': id,
       'email': email,
-      'name': name,
-      'avatar': avatar,
-      'desa_id': desaId,
-      'desa': desa?.toJson(),
-      'role': role,
+      'role_id': roleId,
+      'role': roleName,
       'is_active': isActive,
       'last_login': lastLogin?.toIso8601String(),
       'created_at': createdAt?.toIso8601String(),
       'updated_at': updatedAt?.toIso8601String(),
-    };
-  }
-
-  UserModel copyWith({
-    String? id,
-    String? email,
-    String? name,
-    String? avatar,
-    DesaModel? desa,
-    String? desaId,
-    String? role,
-    bool? isActive,
-    DateTime? lastLogin,
-    DateTime? createdAt,
-    DateTime? updatedAt,
-  }) {
-    return UserModel(
-      id: id ?? this.id,
-      email: email ?? this.email,
-      name: name ?? this.name,
-      avatar: avatar ?? this.avatar,
-      desa: desa ?? this.desa,
-      desaId: desaId ?? this.desaId,
-      role: role ?? this.role,
-      isActive: isActive ?? this.isActive,
-      lastLogin: lastLogin ?? this.lastLogin,
-      createdAt: createdAt ?? this.createdAt,
-      updatedAt: updatedAt ?? this.updatedAt,
-    );
-  }
-}
-
-class User {
-  final String? id;
-  final String? name;
-  final String? email;
-  final String? phone;
-  final String? role;
-  final String? token;
-
-  User({
-    this.id,
-    this.name,
-    this.email,
-    this.phone,
-    this.role,
-    this.token,
-  });
-
-  factory User.fromJson(Map<String, dynamic> json) {
-    return User(
-      id: json['id'],
-      name: json['name'],
-      email: json['email'],
-      phone: json['phone'],
-      role: json['role'],
-      token: json['token'],
-    );
-  }
-
-  Map<String, dynamic> toJson() {
-    return {
-      'id': id,
       'name': name,
-      'email': email,
-      'phone': phone,
-      'role': role,
-      'token': token,
+      'desa': desa?.toJson(),
     };
   }
 }
+
+// Class untuk menampung data user lengkap (BaseUserModel + data spesifik role)
+class UserData<T> {
+  final BaseUserModel baseUser;
+  final T roleData;
+
+  UserData({
+    required this.baseUser,
+    required this.roleData,
+  });
+}
diff --git a/lib/app/data/models/warga_model.dart b/lib/app/data/models/warga_model.dart
index 2c3393b..9a4b00a 100644
--- a/lib/app/data/models/warga_model.dart
+++ b/lib/app/data/models/warga_model.dart
@@ -1,41 +1,44 @@
 import 'dart:convert';
+import 'package:penyaluran_app/app/data/models/desa_model.dart';
 
 // warga == penerima bantuan
 class WargaModel {
-  final String? id;
-  final String? nama;
-  final String? nik;
+  final String id; // Primary key yang juga foreign key ke auth.users(id)
+  final String? desaId;
+  final String? namaLengkap;
   final String? alamat;
-  final String? desa;
-  final String? kecamatan;
-  final String? kabupaten;
-  final String? provinsi;
-  final String? telepon;
+  final String? noHp;
   final String? email;
+  final String? nik;
+  final String? tempatLahir;
+  final DateTime? tanggalLahir;
+  final String? jenisKelamin;
+  final String? agama;
+  final String? kategoriEkonomi;
+  final String? status;
   final String? catatan;
-  final String? kategori; // Contoh: 'lansia', 'disabilitas', 'miskin', dll
-  final String? status; // Contoh: 'AKTIF', 'NONAKTIF'
-  final String? lokasiPenyaluranId; // Referensi ke LokasiPenyaluran
   final DateTime? createdAt;
   final DateTime? updatedAt;
+  final DesaModel? desa;
 
   WargaModel({
-    this.id,
-    this.nama,
-    this.nik,
+    required this.id,
+    this.desaId,
+    this.namaLengkap,
     this.alamat,
-    this.desa,
-    this.kecamatan,
-    this.kabupaten,
-    this.provinsi,
-    this.telepon,
+    this.noHp,
     this.email,
+    this.nik,
+    this.tempatLahir,
+    this.tanggalLahir,
+    this.jenisKelamin,
+    this.agama,
+    this.kategoriEkonomi,
+    this.status = 'AKTIF',
     this.catatan,
-    this.kategori,
-    this.status,
-    this.lokasiPenyaluranId,
     this.createdAt,
     this.updatedAt,
+    this.desa,
   });
 
   factory WargaModel.fromRawJson(String str) =>
@@ -43,45 +46,58 @@ class WargaModel {
 
   String toRawJson() => json.encode(toJson());
 
-  factory WargaModel.fromJson(Map<String, dynamic> json) => WargaModel(
-        id: json["id"],
-        nama: json["nama"],
-        nik: json["nik"],
-        alamat: json["alamat"],
-        desa: json["desa"],
-        kecamatan: json["kecamatan"],
-        kabupaten: json["kabupaten"],
-        provinsi: json["provinsi"],
-        telepon: json["telepon"] ?? json["no_telp"],
-        email: json["email"],
-        catatan: json["catatan"],
-        kategori: json["kategori"],
-        status: json["status"],
-        lokasiPenyaluranId: json["lokasi_penyaluran_id"],
-        createdAt: json["created_at"] != null
-            ? DateTime.parse(json["created_at"])
-            : null,
-        updatedAt: json["updated_at"] != null
-            ? DateTime.parse(json["updated_at"])
-            : null,
-      );
+  factory WargaModel.fromJson(Map<String, dynamic> json) {
+    DesaModel? desa;
+    if (json["desa"] != null && json["desa"] is Map<String, dynamic>) {
+      desa = DesaModel.fromJson(json["desa"]);
+    }
+
+    return WargaModel(
+      id: json["id"],
+      desaId: json["desa_id"],
+      namaLengkap: json["nama_lengkap"],
+      alamat: json["alamat"],
+      noHp: json["no_hp"],
+      email: json["email"],
+      nik: json["nik"],
+      tempatLahir: json["tempat_lahir"],
+      tanggalLahir: json["tanggal_lahir"] != null
+          ? DateTime.parse(json["tanggal_lahir"])
+          : null,
+      jenisKelamin: json["jenis_kelamin"],
+      agama: json["agama"],
+      kategoriEkonomi: json["kategori_ekonomi"],
+      status: json["status"] ?? 'AKTIF',
+      catatan: json["catatan"],
+      createdAt: json["created_at"] != null
+          ? DateTime.parse(json["created_at"])
+          : null,
+      updatedAt: json["updated_at"] != null
+          ? DateTime.parse(json["updated_at"])
+          : null,
+      desa: desa,
+    );
+  }
 
   Map<String, dynamic> toJson() => {
         "id": id,
-        "nama": nama,
-        "nik": nik,
+        "desa_id": desaId,
+        "nama_lengkap": namaLengkap,
         "alamat": alamat,
-        "desa": desa,
-        "kecamatan": kecamatan,
-        "kabupaten": kabupaten,
-        "provinsi": provinsi,
-        "telepon": telepon,
+        "no_hp": noHp,
         "email": email,
-        "catatan": catatan,
-        "kategori": kategori,
+        "nik": nik,
+        "tempat_lahir": tempatLahir,
+        "tanggal_lahir": tanggalLahir?.toIso8601String(),
+        "jenis_kelamin": jenisKelamin,
+        "agama": agama,
+        "kategori_ekonomi": kategoriEkonomi,
         "status": status,
-        "lokasi_penyaluran_id": lokasiPenyaluranId,
+        "catatan": catatan,
         "created_at": createdAt?.toIso8601String(),
         "updated_at": updatedAt?.toIso8601String(),
       };
+
+  // Helper method untuk mendapatkan nama yang ditampilkan
+  String get displayName => namaLengkap ?? 'Warga';
 }
diff --git a/lib/app/data/providers/auth_provider.dart b/lib/app/data/providers/auth_provider.dart
index 921ca54..39fae41 100644
--- a/lib/app/data/providers/auth_provider.dart
+++ b/lib/app/data/providers/auth_provider.dart
@@ -1,44 +1,162 @@
 import 'package:penyaluran_app/app/services/supabase_service.dart';
 import 'package:penyaluran_app/app/data/models/user_model.dart';
+import 'package:penyaluran_app/app/data/models/warga_model.dart';
+import 'package:penyaluran_app/app/data/models/petugas_desa_model.dart';
+import 'package:penyaluran_app/app/data/models/donatur_model.dart';
+import 'package:penyaluran_app/app/data/models/desa_model.dart';
 
 class AuthProvider {
   final SupabaseService _supabaseService = SupabaseService.to;
 
-  // Cache untuk menyimpan data profil pengguna
-  UserModel? _cachedUser;
+  // Cache untuk menyimpan data pengguna
+  UserData? _cachedUserData;
 
   // Metode untuk login
-  Future<UserModel?> signIn(String email, String password) async {
+  Future<UserData?> signIn(String email, String password) async {
     try {
-      final response = await _supabaseService.signIn(email, password);
+      // Step 1: Login
+      final response = await _supabaseService.client.auth.signInWithPassword(
+        email: email,
+        password: password,
+      );
 
-      if (response.user != null && response.user?.email != null) {
-        // Ambil profil pengguna dari database
-        final profileData = await _supabaseService.getUserProfile();
-        print('DEBUG: Profile data dari signIn: $profileData');
-
-        if (profileData != null) {
-          // Buat UserModel dengan data yang ada
-          _cachedUser = UserModel.fromJson({
-            ...profileData,
-            'id': response.user!.id,
-            'email': response.user!.email!,
-          });
-          print(
-              'DEBUG: User model dibuat: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
-          return _cachedUser;
-        }
-
-        // Jika profil belum tersedia, gunakan data default
-        _cachedUser = UserModel(
-          id: response.user!.id,
-          email: response.user!.email!,
-          role: 'WARGA', // Default role
-        );
-        print('DEBUG: User model default dibuat: ${_cachedUser?.email}');
-        return _cachedUser;
+      final user = response.user;
+      if (user == null) {
+        print('Login gagal!');
+        return null;
       }
-      return null;
+
+      final userId = user.id;
+
+      // Step 2: Ambil role dari view `users_with_roles` atau tabel roles
+      String roleName;
+      try {
+        final roleResponse = await _supabaseService.client
+            .from('users_with_roles')
+            .select('role_name')
+            .eq('id', userId)
+            .single();
+
+        roleName = roleResponse['role_name'];
+      } catch (e) {
+        print('Error mengambil role dari users_with_roles: $e');
+        print('Mencoba ambil role dari tabel roles...');
+
+        // Fallback ke cara lama jika view users_with_roles tidak tersedia
+        try {
+          // Ambil role_id dari user metadata
+          final roleId = user.userMetadata?['role_id'];
+          if (roleId == null) {
+            print('Tidak ada role_id di user metadata');
+            return null;
+          }
+
+          final roleResponse = await _supabaseService.client
+              .from('roles')
+              .select('role_name')
+              .eq('id', roleId)
+              .single();
+
+          roleName = roleResponse['role_name'];
+        } catch (e) {
+          print('Error mengambil role dari tabel roles: $e');
+          return null;
+        }
+      }
+
+      print('Role: $roleName');
+
+      // Step 3: Ambil profil user berdasarkan role
+      Map<String, dynamic>? profileResponse;
+      dynamic roleData;
+      DesaModel? desa;
+
+      // Buat BaseUserModel
+      final baseUser = BaseUserModel(
+        id: userId,
+        email: user.email ?? '',
+        roleId: user.userMetadata?['role_id'],
+        roleName: roleName,
+        createdAt: DateTime.parse(user.createdAt),
+        updatedAt:
+            user.updatedAt != null ? DateTime.parse(user.updatedAt!) : null,
+      );
+
+      if (roleName == 'warga') {
+        profileResponse = await _supabaseService.client
+            .from('warga')
+            .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+            .eq('id', userId)
+            .single();
+
+        if (profileResponse != null) {
+          // Ekstrak data desa jika ada
+          if (profileResponse['desa'] != null) {
+            desa = DesaModel.fromJson(profileResponse['desa']);
+            print('Data Desa: ${desa.nama}');
+          }
+
+          roleData = WargaModel.fromJson(profileResponse);
+          print('Data Warga: ${roleData.namaLengkap}');
+        } else {
+          print('Tidak menemukan data warga untuk ID: $userId');
+          return null;
+        }
+      } else if (roleName == 'petugas_desa') {
+        profileResponse = await _supabaseService.client
+            .from('petugas_desa')
+            .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+            .eq('id', userId)
+            .single();
+
+        if (profileResponse != null) {
+          // Ekstrak data desa jika ada
+          if (profileResponse['desa'] != null) {
+            desa = DesaModel.fromJson(profileResponse['desa']);
+            print('Data Desa: ${desa.nama}');
+          }
+
+          roleData = PetugasDesaModel.fromJson(profileResponse);
+          print(
+              'Data Petugas Desa: ${roleData.namaLengkap}, Desa: ${roleData.desa?.nama}');
+        }
+      } else if (roleName == 'donatur') {
+        profileResponse = await _supabaseService.client
+            .from('donatur')
+            .select('*')
+            .eq('id', userId)
+            .single();
+
+        roleData = DonaturModel.fromJson(profileResponse);
+        print('Data Donatur: ${roleData.namaLengkap}');
+      } else {
+        return null;
+      }
+
+      if (roleData == null) {
+        print('Tidak menemukan data profil untuk role: $roleName');
+        return null;
+      }
+
+      // Perbarui baseUser dengan data desa jika ada
+      final updatedBaseUser = BaseUserModel(
+        id: baseUser.id,
+        email: baseUser.email,
+        roleId: baseUser.roleId,
+        roleName: baseUser.roleName,
+        createdAt: baseUser.createdAt,
+        updatedAt: baseUser.updatedAt,
+        desa: desa, // Set desa dari data yang diambil
+      );
+
+      // Simpan cache user data
+      final userData = UserData(
+        baseUser: updatedBaseUser,
+        roleData: roleData,
+      );
+      _cachedUserData = userData;
+
+      return userData;
     } catch (e) {
       print('Error pada signIn: $e');
       rethrow;
@@ -49,57 +167,159 @@ class AuthProvider {
   Future<void> signOut() async {
     try {
       await _supabaseService.signOut();
-      _cachedUser = null; // Hapus cache saat logout
+      _cachedUserData = null; // Hapus cache saat logout
     } catch (e) {
       rethrow;
     }
   }
 
   // Metode untuk mendapatkan user saat ini
-  Future<UserModel?> getCurrentUser() async {
-    // Jika ada cache dan user masih terautentikasi, gunakan cache
-    if (_cachedUser != null && _supabaseService.isAuthenticated) {
-      print(
-          'DEBUG: Menggunakan data user dari cache: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
-      return _cachedUser;
+  Future<UserData?> getCurrentUser({bool skipCache = false}) async {
+    // Jika ada cache dan user masih terautentikasi, gunakan cache kecuali skipCache = true
+    if (!skipCache &&
+        _cachedUserData != null &&
+        _supabaseService.isAuthenticated) {
+      print('DEBUG: Menggunakan data user dari cache');
+      return _cachedUserData;
     }
 
-    final user = _supabaseService.currentUser;
-    if (user != null) {
+    if (_supabaseService.currentUser != null) {
       try {
-        // Ambil profil pengguna dari database
-        final profileData = await _supabaseService.getUserProfile();
-        print('DEBUG: Profile data dari getCurrentUser: $profileData');
+        // Login berhasil, lakukan proses yang sama seperti di signIn
+        // tapi dengan user yang sudah ada
+        final user = _supabaseService.currentUser!;
+        final userId = user.id;
 
-        if (profileData != null) {
-          // Buat UserModel dengan data yang ada
-          _cachedUser = UserModel.fromJson({
-            ...profileData,
-            'id': user.id,
-            'email': user.email!,
-          });
-          print(
-              'DEBUG: User model dibuat: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
-          return _cachedUser;
+        // Step 2: Ambil role dari view `users_with_roles` atau tabel roles
+        String roleName;
+        try {
+          final roleResponse = await _supabaseService.client
+              .from('users_with_roles')
+              .select('role_name')
+              .eq('id', userId)
+              .single();
+
+          roleName = roleResponse['role_name'];
+        } catch (e) {
+          print('Error mengambil role dari users_with_roles: $e');
+          print('Mencoba ambil role dari tabel roles...');
+
+          // Fallback ke cara lama jika view users_with_roles tidak tersedia
+          try {
+            // Ambil role_id dari user metadata
+            final roleId = user.userMetadata?['role_id'];
+            if (roleId == null) {
+              print('Tidak ada role_id di user metadata');
+              return null;
+            }
+
+            final roleResponse = await _supabaseService.client
+                .from('roles')
+                .select('role_name')
+                .eq('id', roleId)
+                .single();
+
+            roleName = roleResponse['role_name'];
+          } catch (e) {
+            print('Error mengambil role dari tabel roles: $e');
+            return null;
+          }
         }
 
-        // Jika profil belum tersedia, gunakan data default
-        _cachedUser = UserModel(
-          id: user.id,
-          email: user.email!,
-          role: 'WARGA', // Default role
+        print('Role: $roleName');
+
+        // Step 3: Ambil profil user berdasarkan role
+        Map<String, dynamic>? profileResponse;
+        dynamic roleData;
+        DesaModel? desa;
+
+        // Buat BaseUserModel
+        final baseUser = BaseUserModel(
+          id: userId,
+          email: user.email ?? '',
+          roleId: user.userMetadata?['role_id'],
+          roleName: roleName ?? '',
+          createdAt: DateTime.parse(user.createdAt),
+          updatedAt:
+              user.updatedAt != null ? DateTime.parse(user.updatedAt!) : null,
         );
-        print('DEBUG: User model default dibuat: ${_cachedUser?.email}');
-        return _cachedUser;
+
+        if ((roleName ?? '').toLowerCase() == 'warga') {
+          profileResponse = await _supabaseService.client
+              .from('warga')
+              .select(
+                  '*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+              .eq('id', userId)
+              .single();
+
+          if (profileResponse != null) {
+            // Ekstrak data desa jika ada
+            if (profileResponse['desa'] != null) {
+              desa = DesaModel.fromJson(profileResponse['desa']);
+              print('Data Desa: ${desa.nama}');
+            }
+
+            roleData = WargaModel.fromJson(profileResponse);
+            print('Data Warga: ${roleData.namaLengkap}');
+          } else {
+            print('Tidak menemukan data warga untuk ID: $userId');
+            return null;
+          }
+        } else if (roleName.toLowerCase() == 'petugas_desa') {
+          profileResponse = await _supabaseService.client
+              .from('petugas_desa')
+              .select(
+                  '*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+              .eq('id', userId)
+              .single();
+
+          if (profileResponse != null) {
+            // Ekstrak data desa jika ada
+            if (profileResponse['desa'] != null) {
+              desa = DesaModel.fromJson(profileResponse['desa']);
+              print('Data Desa: ${desa.nama}');
+            }
+
+            roleData = PetugasDesaModel.fromJson(profileResponse);
+          }
+        } else if (roleName.toLowerCase() == 'donatur') {
+          profileResponse = await _supabaseService.client
+              .from('donatur')
+              .select('*')
+              .eq('id', userId)
+              .single();
+
+          if (profileResponse != null) {
+            roleData = DonaturModel.fromJson(profileResponse);
+          }
+        }
+
+        if (roleData == null) {
+          print('Tidak menemukan data profil untuk role: $roleName');
+          return null;
+        }
+
+        // Perbarui baseUser dengan data desa jika ada
+        final updatedBaseUser = BaseUserModel(
+          id: baseUser.id,
+          email: baseUser.email,
+          roleId: baseUser.roleId,
+          roleName: baseUser.roleName,
+          createdAt: baseUser.createdAt,
+          updatedAt: baseUser.updatedAt,
+          desa: desa, // Set desa dari data yang diambil
+        );
+
+        // Simpan cache user data
+        final userData = UserData(
+          baseUser: updatedBaseUser,
+          roleData: roleData,
+        );
+        _cachedUserData = userData;
+
+        return userData;
       } catch (e) {
         print('Error pada getCurrentUser: $e');
-        // Jika terjadi error, kembalikan model dengan data minimal
-        _cachedUser = UserModel(
-          id: user.id,
-          email: user.email!,
-          role: 'WARGA', // Default role
-        );
-        return _cachedUser;
       }
     }
     return null;
@@ -115,31 +335,49 @@ class AuthProvider {
     return await _supabaseService.getWargaByUserId();
   }
 
-  // Metode untuk membuat profil warga
-  Future<void> createWargaProfile({
-    required String nik,
-    required String namaLengkap,
-    required String jenisKelamin,
-    String? noHp,
-    String? alamat,
-    String? tempatLahir,
-    DateTime? tanggalLahir,
-    String? agama,
-  }) async {
-    await _supabaseService.createWargaProfile(
-      nik: nik,
-      namaLengkap: namaLengkap,
-      jenisKelamin: jenisKelamin,
-      noHp: noHp,
-      alamat: alamat,
-      tempatLahir: tempatLahir,
-      tanggalLahir: tanggalLahir,
-      agama: agama,
-    );
+  // // Metode untuk membuat profil donatur
+  // Future<void> createDonaturProfile({
+  //   required String namaLengkap,
+  //   String? instansi,
+  //   String? jabatan,
+  //   String? noHp,
+  //   String? alamat,
+  //   String? desaId,
+  // }) async {
+  //   await _supabaseService.createDonaturProfile(
+  //     namaLengkap: namaLengkap,
+  //     instansi: instansi,
+  //     jabatan: jabatan,
+  //     noHp: noHp,
+  //     alamat: alamat,
+  //     desaId: desaId,
+  //   );
 
-    // Invalidasi cache setelah membuat profil baru
-    _cachedUser = null;
-  }
+  //   // Invalidasi cache setelah membuat profil baru
+  //   _cachedUserData = null;
+  // }
+
+  // // Metode untuk membuat profil petugas desa
+  // Future<void> createPetugasDesaProfile({
+  //   required String namaLengkap,
+  //   String? nip,
+  //   String? jabatan,
+  //   String? noHp,
+  //   String? alamat,
+  //   String? desaId,
+  // }) async {
+  //   await _supabaseService.createPetugasDesaProfile(
+  //     namaLengkap: namaLengkap,
+  //     nip: nip,
+  //     jabatan: jabatan,
+  //     noHp: noHp,
+  //     alamat: alamat,
+  //     desaId: desaId,
+  //   );
+
+  //   // Invalidasi cache setelah membuat profil baru
+  //   _cachedUserData = null;
+  // }
 
   // Metode untuk mendapatkan notifikasi pengguna
   Future<List<Map<String, dynamic>>> getUserNotifications(
diff --git a/lib/app/modules/auth/controllers/auth_controller.dart b/lib/app/modules/auth/controllers/auth_controller.dart
index 92ecdb6..7a807b8 100644
--- a/lib/app/modules/auth/controllers/auth_controller.dart
+++ b/lib/app/modules/auth/controllers/auth_controller.dart
@@ -1,17 +1,51 @@
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
+import 'package:penyaluran_app/app/data/models/donatur_model.dart';
+import 'package:penyaluran_app/app/data/models/petugas_desa_model.dart';
 import 'package:penyaluran_app/app/data/models/user_model.dart';
+import 'package:penyaluran_app/app/data/models/warga_model.dart';
 import 'package:penyaluran_app/app/data/providers/auth_provider.dart';
 import 'package:penyaluran_app/app/routes/app_pages.dart';
-import 'package:penyaluran_app/app/modules/warga/controllers/warga_dashboard_controller.dart';
 
 class AuthController extends GetxController {
   static AuthController get to => Get.find();
 
   final AuthProvider _authProvider = AuthProvider();
 
-  final Rx<UserModel?> _user = Rx<UserModel?>(null);
-  UserModel? get user => _user.value;
+  final Rx<UserData?> _userData = Rx<UserData?>(null);
+  UserData? get userData => _userData.value;
+
+  // Getter untuk BaseUserModel
+  BaseUserModel? get baseUser => _userData.value?.baseUser;
+
+  // Getter untuk role
+  String get role => _userData.value?.baseUser.roleName.toLowerCase() ?? '';
+
+  // Getter dinamis untuk data role-specific
+  dynamic get roleData => _userData.value?.roleData;
+
+  // Getter untuk memeriksa tipe roleData
+  bool get isWarga =>
+      _userData.value?.roleData is WargaModel && role == 'warga';
+  bool get isDonatur =>
+      _userData.value?.roleData is DonaturModel && role == 'donatur';
+  bool get isPetugasDesa =>
+      _userData.value?.roleData is PetugasDesaModel && role == 'petugas_desa';
+
+  // Helper method untuk mendapatkan nama display
+  String get displayName {
+    if (roleData == null) return baseUser?.email ?? 'Pengguna';
+
+    if (isWarga) {
+      return (roleData as WargaModel).displayName;
+    } else if (isDonatur) {
+      return (roleData as DonaturModel).displayName;
+    } else if (isPetugasDesa) {
+      return (roleData as PetugasDesaModel).displayName;
+    }
+
+    return baseUser?.email ?? 'Pengguna';
+  }
 
   final RxBool isLoading = false.obs;
   final RxBool isWargaProfileComplete = false.obs;
@@ -74,21 +108,21 @@ class AuthController extends GetxController {
       print('Memeriksa status autentikasi...');
 
       // Jika user sudah ada di memori dan profil sudah diambil, gunakan data yang ada
-      if (_user.value != null && _hasLoadedProfile.value) {
+      if (_userData.value != null && _hasLoadedProfile.value) {
         print('Menggunakan data user yang sudah ada di memori');
-        _handleAuthenticatedUser(_user.value!);
+        _handleAuthenticatedUser(_userData.value!);
         return;
       }
 
       // Jika belum ada data user, ambil dari provider
-      final currentUser = await _authProvider.getCurrentUser();
+      final currentUserData = await _authProvider.getCurrentUser();
 
-      if (currentUser != null) {
+      if (currentUserData != null) {
         print(
-            'User terautentikasi: ${currentUser.email}, role: ${currentUser.role}');
-        _user.value = currentUser;
+            'User terautentikasi: ${currentUserData.baseUser.email}, role: ${currentUserData.baseUser.roleName}');
+        _userData.value = currentUserData;
         _hasLoadedProfile.value = true;
-        _handleAuthenticatedUser(currentUser);
+        _handleAuthenticatedUser(currentUserData);
       } else {
         print('Tidak ada user yang terautentikasi');
         _handleUnauthenticatedUser();
@@ -104,13 +138,13 @@ class AuthController extends GetxController {
   }
 
   // Metode untuk menangani user yang terautentikasi
-  void _handleAuthenticatedUser(UserModel user) {
+  void _handleAuthenticatedUser(UserData userData) {
     // Hindari navigasi jika sudah berada di halaman yang sesuai
     final currentRoute = Get.currentRoute;
     print('Rute saat ini: $currentRoute');
 
-    // Pastikan role tidak null, gunakan default jika null
-    final role = user.role.isNotEmpty ? user.role : 'WARGA';
+    // Dapatkan role dari BaseUserModel
+    final role = userData.baseUser.roleName.toLowerCase();
     print('Role yang digunakan: $role');
 
     // Untuk semua role, arahkan ke dashboard masing-masing
@@ -146,9 +180,8 @@ class AuthController extends GetxController {
   // Memeriksa status profil warga
   Future<void> checkWargaProfileStatus() async {
     try {
-      if (_user.value?.role == 'WARGA') {
-        final wargaData = await _authProvider.getWargaData();
-        isWargaProfileComplete.value = wargaData != null;
+      if (role == 'warga') {
+        isWargaProfileComplete.value = roleData != null;
       } else {
         isWargaProfileComplete.value = true;
       }
@@ -177,17 +210,14 @@ class AuthController extends GetxController {
     // Bersihkan dependensi form sebelum navigasi
     clearFormDependencies();
 
-    switch (role) {
-      case 'WARGA':
+    switch (role.toLowerCase()) {
+      case 'warga':
         Get.offAllNamed(Routes.wargaDashboard);
         break;
-      case 'PETUGASVERIFIKASI':
-        Get.offAllNamed(Routes.petugasVerifikasiDashboard);
-        break;
-      case 'PETUGASDESA':
+      case 'petugas_desa':
         Get.offAllNamed(Routes.petugasDesaDashboard);
         break;
-      case 'DONATUR':
+      case 'donatur':
         Get.offAllNamed(Routes.donaturDashboard);
         break;
       default:
@@ -229,88 +259,81 @@ class AuthController extends GetxController {
       isLoading.value = true;
 
       print('DEBUG: Memanggil _authProvider.signIn');
-      final user = await _authProvider.signIn(
+      final userData = await _authProvider.signIn(
         email,
         password,
       );
 
-      print('DEBUG: Hasil signIn: ${user != null ? 'Berhasil' : 'Gagal'}');
-      if (user != null) {
-        print('DEBUG: User ditemukan, role: ${user.role}');
-        _user.value = user;
+      print('DEBUG: Hasil signIn: ${userData != null ? 'Berhasil' : 'Gagal'}');
+      if (userData != null) {
+        print('DEBUG: User ditemukan, role: ${userData.baseUser.roleName}');
+        _userData.value = userData;
         _hasLoadedProfile.value = true; // Tandai bahwa profil sudah diambil
         clearControllers();
 
         // Arahkan ke dashboard sesuai peran
-        print('DEBUG: Navigasi berdasarkan peran: ${user.role}');
-        navigateBasedOnRole(user.role);
+        print(
+            'DEBUG: Navigasi berdasarkan peran: ${userData.baseUser.roleName}');
+        navigateBasedOnRole(userData.baseUser.roleName.toLowerCase());
       } else {
         print('DEBUG: User null setelah login berhasil');
+        handleLoginError(Exception('Data pengguna tidak ditemukan'));
       }
     } catch (e) {
-      print('DEBUG: Error detail pada login: $e');
-      print('DEBUG: Stack trace: ${StackTrace.current}');
-      Get.snackbar(
-        'Error',
-        'Login gagal: ${e.toString()}',
-        snackPosition: SnackPosition.TOP,
-        backgroundColor: Colors.red,
-        colorText: Colors.white,
-      );
+      handleLoginError(e);
     } finally {
       print('DEBUG: Mengatur isLoading ke false');
       isLoading.value = false;
     }
   }
 
-  // Metode untuk logout
-  Future<void> logout() async {
-    try {
-      // Ambil semua controller yang mungkin perlu dibersihkan
-      try {
-        final wargaController = Get.find<WargaDashboardController>();
-        wargaController.penerimaPenyaluran.clear();
-        wargaController.pengajuanKelayakan.clear();
-        wargaController.pengaduan.clear();
-      } catch (e) {
-        // Jika controller tidak ditemukan, abaikan
-        print('Controller tidak ditemukan: $e');
-      }
+  // Menangani error saat login
+  void handleLoginError(dynamic error) {
+    print('DEBUG: Error login: $error');
 
-      // Logout dari Supabase
-      await _authProvider.signOut();
+    String errorMessage = 'Terjadi kesalahan saat login. Silakan coba lagi.';
 
-      // Reset semua state
-      _user.value = null;
-      _hasLoadedProfile.value = false;
-      isWargaProfileComplete.value = false;
-
-      // Bersihkan dependensi form sebelum navigasi
-      clearFormDependencies();
-
-      // Navigasi ke halaman login
-      Get.offAllNamed(Routes.login);
-    } catch (e) {
-      Get.snackbar(
-        'Error',
-        'Logout gagal: ${e.toString()}',
-        snackPosition: SnackPosition.TOP,
-        backgroundColor: Colors.red,
-        colorText: Colors.white,
-      );
+    if (error.toString().contains('Invalid login credentials')) {
+      errorMessage = 'Email atau password salah. Silakan coba lagi.';
+    } else if (error.toString().contains('Too many requests')) {
+      errorMessage = 'Terlalu banyak percobaan login. Silakan coba lagi nanti.';
     }
+
+    Get.snackbar(
+      'Error',
+      errorMessage,
+      snackPosition: SnackPosition.TOP,
+      backgroundColor: Colors.red,
+      colorText: Colors.white,
+    );
   }
 
   // Metode untuk membersihkan controller
   void clearControllers() {
+    emailController.clear();
+    passwordController.clear();
+    confirmPasswordController.clear();
+  }
+
+  // Metode untuk logout
+  Future<void> logout() async {
     try {
-      if (emailController.text.isNotEmpty) emailController.clear();
-      if (passwordController.text.isNotEmpty) passwordController.clear();
-      if (confirmPasswordController.text.isNotEmpty) {
-        confirmPasswordController.clear();
-      }
+      isLoading.value = true;
+      await _authProvider.signOut();
+      _userData.value = null;
+      _hasLoadedProfile.value = false;
+      Get.offAllNamed(Routes.login);
     } catch (e) {
-      print('Error clearing controllers: $e');
+      print('Error saat logout: $e');
+      Get.snackbar(
+        'Error',
+        'Terjadi kesalahan saat logout. Silakan coba lagi.',
+        snackPosition: SnackPosition.TOP,
+        backgroundColor: Colors.red,
+        colorText: Colors.white,
+      );
+    } finally {
+      isLoading.value = false;
     }
   }
 
@@ -355,16 +378,42 @@ class AuthController extends GetxController {
     }
   }
 
+  // Metode untuk refresh data user setelah update profil
+  Future<void> refreshUserData() async {
+    try {
+      print('Memperbarui data pengguna...');
+      isLoading.value = true;
+
+      // Hapus cache profil yang sudah tidak valid
+      _hasLoadedProfile.value = false;
+
+      // Ambil data user terbaru dari provider dengan menskip cache
+      final currentUserData =
+          await _authProvider.getCurrentUser(skipCache: true);
+
+      if (currentUserData != null) {
+        print(
+            'Data pengguna berhasil diperbarui: ${currentUserData.baseUser.name}');
+        _userData.value = currentUserData;
+        _hasLoadedProfile.value = true;
+      } else {
+        print('Gagal memperbarui data pengguna');
+      }
+    } catch (e) {
+      print('Error refreshing user data: $e');
+    } finally {
+      isLoading.value = false;
+    }
+  }
+
   // Mendapatkan rute target berdasarkan role
   String _getTargetRouteForRole(String role) {
-    switch (role) {
-      case 'WARGA':
+    switch (role.toLowerCase()) {
+      case 'warga':
         return Routes.wargaDashboard;
-      case 'PETUGASVERIFIKASI':
-        return Routes.petugasVerifikasiDashboard;
-      case 'PETUGASDESA':
+      case 'petugas_desa':
         return Routes.petugasDesaDashboard;
-      case 'DONATUR':
+      case 'donatur':
         return Routes.donaturDashboard;
       default:
         return Routes.home;
diff --git a/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart b/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart
index 2c378d4..5e59518 100644
--- a/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart
+++ b/lib/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart
@@ -34,6 +34,7 @@ class LaporanPenyaluranController extends GetxController {
   final RxMap<String, dynamic> lokasiPenyaluran = RxMap<String, dynamic>();
   final RxMap<String, dynamic> desaData = RxMap<String, dynamic>();
   final RxMap<String, dynamic> kategoriBantuan = RxMap<String, dynamic>();
+  final RxMap<String, dynamic> petugasData = RxMap<String, dynamic>();
 
   // Form controllers
   final TextEditingController judulController = TextEditingController();
@@ -53,8 +54,8 @@ class LaporanPenyaluranController extends GetxController {
   final RxString filterStatus = 'SEMUA'.obs;
 
   // Getter untuk data user
-  get user => _authController.user;
-  String get role => user?.role ?? 'WARGA';
+  dynamic get user => _authController.baseUser;
+  String get role => _authController.role;
 
   @override
   void onInit() {
@@ -168,6 +169,8 @@ class LaporanPenyaluranController extends GetxController {
           .single();
 
       selectedPenyaluran.value = PenyaluranBantuanModel.fromJson(response);
+      print(
+          'PenyaluranDetail - petugasId: ${selectedPenyaluran.value?.petugasId}');
 
       // Ambil data penerima terkait
       await fetchPenerimaPenyaluran(penyaluranId);
@@ -178,6 +181,11 @@ class LaporanPenyaluranController extends GetxController {
             selectedPenyaluran.value!.lokasiPenyaluranId!);
       }
 
+      // Ambil data petugas jika ada
+      if (selectedPenyaluran.value?.petugasId != null) {
+        await fetchPetugasData(selectedPenyaluran.value!.petugasId!);
+      }
+
       // Hitung penggunaan stok bantuan
       await calculateStokBantuanUsage(penyaluranId);
     } catch (e) {
@@ -251,6 +259,22 @@ class LaporanPenyaluranController extends GetxController {
     }
   }
 
+  // Mendapatkan data petugas
+  Future<void> fetchPetugasData(String petugasId) async {
+    try {
+      final response = await _supabaseService.client
+          .from('petugas_desa')
+          .select('*, desa(nama)')
+          .eq('id', petugasId)
+          .single();
+
+      petugasData.value = response;
+      print('Data petugas berhasil diambil: $petugasData');
+    } catch (e) {
+      print('Error fetching petugas data: $e');
+    }
+  }
+
   // Menghitung penggunaan stok bantuan
   Future<void> calculateStokBantuanUsage(String penyaluranId) async {
     try {
@@ -563,7 +587,8 @@ class LaporanPenyaluranController extends GetxController {
       // Load logo - tidak perlu menampilkan error jika logo tidak ada
       pw.MemoryImage? logoImage;
       try {
-        final logoBytes = await rootBundle.load('assets/img/logo.png');
+        final logoBytes =
+            await rootBundle.load('assets/images/penyaluran-icon.png');
         logoImage = pw.MemoryImage(logoBytes.buffer.asUint8List());
       } catch (e) {
         // Logo tidak ditemukan - tidak perlu print error
@@ -600,7 +625,7 @@ class LaporanPenyaluranController extends GetxController {
                   children: [
                     logoImage != null
                         ? pw.Image(logoImage, width: 60, height: 60)
-                        : pw.SizedBox(width: 60),
+                        : pw.SizedBox(width: 10, height: 10),
                     pw.Column(
                       crossAxisAlignment: pw.CrossAxisAlignment.end,
                       children: [
@@ -924,10 +949,7 @@ class LaporanPenyaluranController extends GetxController {
                                 isHeader: true,
                                 align: pw.TextAlign.center,
                                 color: PdfColors.blue900),
-                            _buildPdfTableCell('Satuan', ttfBold,
-                                isHeader: true,
-                                align: pw.TextAlign.center,
-                                color: PdfColors.blue900),
+
                             _buildPdfTableCell('Status', ttfBold,
                                 isHeader: true,
                                 align: pw.TextAlign.center,
@@ -947,13 +969,19 @@ class LaporanPenyaluranController extends GetxController {
                               ? '${penerima.jumlahBantuan} ${penerima.satuan ?? ''}'
                               : '-';
 
+                          final isUang =
+                              penerima.satuan?.toLowerCase() == 'rupiah';
+                          final jumlahBantuan = penerima.jumlahBantuan ?? 0;
+
+                          final formattedJumlah = isUang
+                              ? 'Rp ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(jumlahBantuan)}'
+                              : '$jumlahBantuan ${penerima.satuan ?? ''}';
+
                           return pw.TableRow(
                             children: [
                               _buildPdfTableCell(nik, ttf),
                               _buildPdfTableCell(wargaNama, ttf),
-                              _buildPdfTableCell(jumlah, ttf,
-                                  align: pw.TextAlign.center),
-                              _buildPdfTableCell(penerima.satuan ?? '-', ttf,
+                              _buildPdfTableCell(formattedJumlah, ttf,
                                   align: pw.TextAlign.center),
                               _buildPdfTableCell(
                                   penerima.statusPenerimaan ?? '-', ttf,
@@ -1005,12 +1033,17 @@ class LaporanPenyaluranController extends GetxController {
                           'Dokumentasi dapat diakses melalui tautan berikut:',
                           style: pw.TextStyle(font: ttf)),
                       pw.SizedBox(height: 3),
-                      pw.Text(laporan.dokumentasiUrl!,
+                      pw.UrlLink(
+                        destination: laporan.dokumentasiUrl!,
+                        child: pw.Text(
+                          laporan.dokumentasiUrl!,
                           style: pw.TextStyle(
                             font: ttf,
                             color: PdfColors.blue,
                             decoration: pw.TextDecoration.underline,
-                          )),
+                          ),
+                        ),
+                      ),
                       if (laporan.beritaAcaraUrl != null)
                         pw.SizedBox(height: 10),
                     ],
@@ -1024,12 +1057,17 @@ class LaporanPenyaluranController extends GetxController {
                           'Berita acara dapat diakses melalui tautan berikut:',
                           style: pw.TextStyle(font: ttf)),
                       pw.SizedBox(height: 3),
-                      pw.Text(laporan.beritaAcaraUrl!,
+                      pw.UrlLink(
+                        destination: laporan.beritaAcaraUrl!,
+                        child: pw.Text(
+                          laporan.beritaAcaraUrl!,
                           style: pw.TextStyle(
                             font: ttf,
                             color: PdfColors.blue,
                             decoration: pw.TextDecoration.underline,
-                          )),
+                          ),
+                        ),
+                      ),
                     ],
                   ],
                   ttfBold,
@@ -1046,7 +1084,9 @@ class LaporanPenyaluranController extends GetxController {
                     crossAxisAlignment: pw.CrossAxisAlignment.center,
                     children: [
                       pw.Text(
-                        'Penanggung Jawab,',
+                        petugasData.isNotEmpty
+                            ? 'Petugas ${petugasData['desa'] != null ? "Desa " + (petugasData['desa']['nama'] ?? '') : ''}'
+                            : 'Penanggung Jawab,',
                         style: pw.TextStyle(font: ttf),
                       ),
                       pw.SizedBox(height: 50), // Ruang untuk tanda tangan
@@ -1057,12 +1097,23 @@ class LaporanPenyaluranController extends GetxController {
                                 top: pw.BorderSide(color: PdfColors.black))),
                         padding: const pw.EdgeInsets.only(top: 5),
                         child: pw.Text(
-                          // Sesuaikan dengan properti yang ada di model user
-                          user?.email ?? 'Admin Sistem',
+                          // Gunakan data petugas dari penyaluran, jika tidak ada gunakan data user
+                          petugasData.isNotEmpty
+                              ? petugasData['nama_lengkap'] ?? 'Petugas Desa'
+                              : user?.nama ?? 'Admin Sistem',
                           style: pw.TextStyle(font: ttfBold),
                           textAlign: pw.TextAlign.center,
                         ),
                       ),
+
+                      // NIP atau nomor identitas petugas
+                      pw.Text(
+                        petugasData.isNotEmpty
+                            ? petugasData['nip'] ?? '-'
+                            : user?.nip ?? '-',
+                        style: pw.TextStyle(font: ttf),
+                        textAlign: pw.TextAlign.center,
+                      ),
                     ],
                   ),
                 ],
diff --git a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart
index fdfbe7e..bd6b1b4 100644
--- a/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart
+++ b/lib/app/modules/laporan_penyaluran/views/laporan_penyaluran_detail_view.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:penyaluran_app/app/modules/laporan_penyaluran/controllers/laporan_penyaluran_controller.dart';
 import 'package:penyaluran_app/app/theme/app_theme.dart';
+import 'package:penyaluran_app/app/utils/date_time_helper.dart';
 import 'package:penyaluran_app/app/widgets/custom_app_bar.dart';
 import 'package:penyaluran_app/app/widgets/section_header.dart';
 import 'package:penyaluran_app/app/widgets/status_badge.dart';
@@ -185,15 +186,15 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
                         _buildInfoRow(
                           'Tanggal Penyaluran',
                           penyaluran.tanggalPenyaluran != null
-                              ? DateFormat('dd/MM/yyyy')
-                                  .format(penyaluran.tanggalPenyaluran!)
+                              ? DateTimeHelper.formatDateTime(
+                                  penyaluran.tanggalPenyaluran!)
                               : '-',
                         ),
                         _buildInfoRow(
                           'Tanggal Selesai',
                           penyaluran.tanggalSelesai != null
-                              ? DateFormat('dd/MM/yyyy')
-                                  .format(penyaluran.tanggalSelesai!)
+                              ? DateTimeHelper.formatDateTime(
+                                  penyaluran.tanggalSelesai!)
                               : '-',
                         ),
                         _buildInfoRow('Jumlah Penerima',
@@ -525,7 +526,7 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
                                   Expanded(
                                     flex: 3,
                                     child: Text(
-                                      'Nama Penerima',
+                                      'NIK',
                                       style: TextStyle(
                                           fontWeight: FontWeight.bold),
                                     ),
@@ -533,7 +534,7 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
                                   Expanded(
                                     flex: 3,
                                     child: Text(
-                                      'Jenis Bantuan',
+                                      'Nama Penerima',
                                       style: TextStyle(
                                           fontWeight: FontWeight.bold),
                                     ),
@@ -568,12 +569,13 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
                               itemBuilder: (context, index) {
                                 final penerima =
                                     controller.daftarPenerima[index];
+                                final wargaNik = penerima.warga != null
+                                    ? penerima.warga!['nik'] ?? '-'
+                                    : '-';
                                 final wargaNama = penerima.warga != null
                                     ? penerima.warga!['nama_lengkap'] ?? '-'
                                     : '-';
-                                final stokNama = penerima.stokBantuan != null
-                                    ? penerima.stokBantuan!['nama'] ?? '-'
-                                    : '-';
+
                                 final jumlah = penerima.jumlahBantuan != null
                                     ? '${penerima.jumlahBantuan} ${penerima.satuan ?? ''}'
                                     : '-';
@@ -591,11 +593,11 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
                                     children: [
                                       Expanded(
                                         flex: 3,
-                                        child: Text(wargaNama),
+                                        child: Text(wargaNik),
                                       ),
                                       Expanded(
                                         flex: 3,
-                                        child: Text(stokNama),
+                                        child: Text(wargaNama),
                                       ),
                                       Expanded(
                                         flex: 2,
@@ -867,9 +869,7 @@ class LaporanPenyaluranDetailView extends GetView<LaporanPenyaluranController> {
               ),
               const SizedBox(height: 6),
               Text(
-                tanggalLaporan != null
-                    ? DateFormat('dd/MM/yyyy').format(tanggalLaporan)
-                    : '-',
+                DateTimeHelper.formatDateTime(tanggalLaporan),
                 style: const TextStyle(
                   fontSize: 14,
                   fontWeight: FontWeight.bold,
diff --git a/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart b/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart
index de1136e..26e9b34 100644
--- a/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/detail_penyaluran_controller.dart
@@ -54,12 +54,12 @@ class DetailPenyaluranController extends GetxController {
       final user = _supabaseService.client.auth.currentUser;
       if (user != null) {
         final userData = await _supabaseService.client
-            .from('users')
+            .from('user_profile')
             .select('role')
             .eq('id', user.id)
             .single();
 
-        if (userData['role'] == 'petugas_desa') {
+        if (userData['role'] == 'PETUGASDESA') {
           isPetugasDesa.value = true;
         }
       }
diff --git a/lib/app/modules/petugas_desa/controllers/donatur_controller.dart b/lib/app/modules/petugas_desa/controllers/donatur_controller.dart
index 6fa1327..678a3db 100644
--- a/lib/app/modules/petugas_desa/controllers/donatur_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/donatur_controller.dart
@@ -275,7 +275,7 @@ class DonaturController extends GetxController {
 
     try {
       final donatur = daftarDonatur.firstWhere((d) => d.id == donaturId);
-      return donatur.nama;
+      return donatur.namaLengkap;
     } catch (e) {
       return null;
     }
diff --git a/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart b/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart
index 5f11f5b..95a4d6d 100644
--- a/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart
@@ -47,7 +47,7 @@ class JadwalPenyaluranController extends GetxController {
   // Controller untuk pencarian
   final TextEditingController searchController = TextEditingController();
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   @override
   void onInit() {
diff --git a/lib/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart b/lib/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart
index d3feeb6..eae4b11 100644
--- a/lib/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart
@@ -32,7 +32,7 @@ class PenerimaBantuanController extends GetxController {
   // Form key
   final GlobalKey<FormState> penerimaFormKey = GlobalKey<FormState>();
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   @override
   void onInit() {
@@ -79,19 +79,21 @@ class PenerimaBantuanController extends GetxController {
 
     isLoading.value = true;
     try {
-      final penerima = WargaModel(
-        nama: namaController.text,
-        nik: nikController.text,
-        alamat: alamatController.text,
-        telepon: teleponController.text,
-        email: emailController.text,
-        catatan: catatanController.text,
-        status: 'AKTIF',
-        createdAt: DateTime.now(),
-        updatedAt: DateTime.now(),
-      );
+      // Biarkan Supabase yang akan menghasilkan ID saat insert
+      // Kita hanya perlu menyediakan data lainnya
+      final penerima = {
+        'nama_lengkap': namaController.text,
+        'nik': nikController.text,
+        'alamat': alamatController.text,
+        'no_hp': teleponController.text,
+        'email': emailController.text,
+        'catatan': catatanController.text,
+        'status': 'AKTIF',
+        'created_at': DateTime.now().toIso8601String(),
+        'updated_at': DateTime.now().toIso8601String(),
+      };
 
-      await _supabaseService.tambahPenerima(penerima.toJson());
+      await _supabaseService.tambahPenerima(penerima);
 
       // Clear form
       clearForm();
@@ -125,18 +127,17 @@ class PenerimaBantuanController extends GetxController {
 
     isLoading.value = true;
     try {
-      final penerima = WargaModel(
-        id: penerimaId,
-        nama: namaController.text,
-        nik: nikController.text,
-        alamat: alamatController.text,
-        telepon: teleponController.text,
-        email: emailController.text,
-        catatan: catatanController.text,
-        updatedAt: DateTime.now(),
-      );
+      final penerima = {
+        'nama_lengkap': namaController.text,
+        'nik': nikController.text,
+        'alamat': alamatController.text,
+        'no_hp': teleponController.text,
+        'email': emailController.text,
+        'catatan': catatanController.text,
+        'updated_at': DateTime.now().toIso8601String(),
+      };
 
-      await _supabaseService.updatePenerima(penerimaId, penerima.toJson());
+      await _supabaseService.updatePenerima(penerimaId, penerima);
 
       // Clear form
       clearForm();
@@ -218,10 +219,10 @@ class PenerimaBantuanController extends GetxController {
   }
 
   void setFormData(WargaModel penerima) {
-    namaController.text = penerima.nama ?? '';
+    namaController.text = penerima.namaLengkap ?? '';
     nikController.text = penerima.nik ?? '';
     alamatController.text = penerima.alamat ?? '';
-    teleponController.text = penerima.telepon ?? '';
+    teleponController.text = penerima.noHp ?? '';
     emailController.text = penerima.email ?? '';
     catatanController.text = penerima.catatan ?? '';
   }
diff --git a/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart b/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
index 4a94fc5..ca45d09 100644
--- a/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/pengaduan_controller.dart
@@ -37,7 +37,7 @@ class PengaduanController extends GetxController {
   // Image picker
   final ImagePicker _imagePicker = ImagePicker();
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   @override
   void onInit() {
diff --git a/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart b/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart
index 113a847..ebc21f7 100644
--- a/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/penitipan_bantuan_controller.dart
@@ -53,7 +53,7 @@ class PenitipanBantuanController extends GetxController {
   // Tambahkan properti untuk waktu terakhir update
   final Rx<DateTime> lastUpdateTime = DateTime.now().obs;
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   // Getter untuk counter dari CounterService
   RxInt get jumlahMenunggu => _counterService.jumlahMenunggu;
@@ -72,10 +72,9 @@ class PenitipanBantuanController extends GetxController {
 
     loadPenitipanData();
     loadKategoriBantuanData();
-    // Tambahkan delay untuk memastikan data petugas desa dimuat setelah penitipan
-    Future.delayed(const Duration(seconds: 1), () {
-      loadAllPetugasDesaData();
-    });
+
+    // Hapus delay dan muat data petugas desa langsung
+    loadAllPetugasDesaData();
 
     // Listener untuk pencarian donatur
     donaturSearchController.addListener(() {
@@ -123,25 +122,24 @@ class PenitipanBantuanController extends GetxController {
         // Muat informasi petugas desa untuk item yang terverifikasi
         print(
             'Memuat informasi petugas desa untuk ${daftarPenitipan.length} penitipan');
+
+        List<Future> petugasLoaders = [];
+
         for (var item in daftarPenitipan) {
           if (item.status == 'TERVERIFIKASI' && item.petugasDesaId != null) {
             print(
                 'Memuat informasi petugas desa untuk penitipan ID: ${item.id}, petugasDesaId: ${item.petugasDesaId}');
-            final petugasData = await getPetugasDesaInfo(item.petugasDesaId);
-            if (petugasData != null) {
-              print(
-                  'Berhasil memuat data petugas desa: ${petugasData['name']} untuk ID: ${item.petugasDesaId}');
-            } else {
-              print(
-                  'Gagal memuat data petugas desa untuk ID: ${item.petugasDesaId}');
-            }
+            petugasLoaders.add(getPetugasDesaInfo(item.petugasDesaId));
           }
         }
 
+        // Tunggu semua data petugas desa selesai dimuat
+        await Future.wait(petugasLoaders);
+
         // Debug: print semua data petugas desa yang sudah dimuat
         print('Data petugas desa yang sudah dimuat:');
         petugasDesaCache.forEach((key, value) {
-          print('ID: $key, Nama: $value');
+          print('ID: $key, Nama: ${value['nama_lengkap']}');
         });
 
         // Update waktu terakhir refresh
@@ -490,7 +488,8 @@ class PenitipanBantuanController extends GetxController {
         final donaturId = item.donaturId;
         String donaturNama = '';
         if (donaturId != null && donaturCache.containsKey(donaturId)) {
-          donaturNama = donaturCache[donaturId]?.nama?.toLowerCase() ?? '';
+          donaturNama =
+              donaturCache[donaturId]?.namaLengkap?.toLowerCase() ?? '';
         }
         final donaturMatch = donaturNama.contains(searchText);
 
@@ -551,25 +550,37 @@ class PenitipanBantuanController extends GetxController {
     if (!petugasDesaCache.containsKey(petugasDesaId)) {
       print(
           'Data petugas desa tidak ditemukan di cache untuk ID: $petugasDesaId');
-      // Jadwalkan pengambilan data untuk nanti
+      // Muat data petugas dan perbarui UI
       loadPetugasDesaData(petugasDesaId);
-      return 'Memuat...';
+
+      // Coba cek lagi setelah pemuatan
+      if (petugasDesaCache.containsKey(petugasDesaId)) {
+        // Akses nama dari struktur data petugas_desa
+        final nama = petugasDesaCache[petugasDesaId]?['nama_lengkap'];
+        return nama ?? 'Tidak diketahui';
+      }
+
+      return 'Memuat data...';
     }
 
     // Sekarang data seharusnya ada di cache
-    final nama = petugasDesaCache[petugasDesaId]?['name'];
+    // Akses nama dari struktur data petugas_desa
+    final nama = petugasDesaCache[petugasDesaId]?['nama_lengkap'];
     print('Nama petugas desa: $nama untuk ID: $petugasDesaId');
     return nama ?? 'Tidak diketahui';
   }
 
   // Fungsi untuk memuat data petugas desa dan memperbarui UI
-  void loadPetugasDesaData(String petugasDesaId) async {
+  Future<void> loadPetugasDesaData(String petugasDesaId) async {
     try {
+      print('Memuat data petugas desa untuk ID: $petugasDesaId');
       final petugasData = await getPetugasDesaInfo(petugasDesaId);
       if (petugasData != null) {
         // Data sudah dimasukkan ke cache oleh getPetugasDesaInfo
-        // Refresh UI
-        update();
+        print('Berhasil memuat data petugas: ${petugasData['nama_lengkap']}');
+
+        // Refresh UI segera
+        update(['petugas_data']);
       } else {
         print(
             'Gagal mengambil data petugas desa dari server untuk ID: $petugasDesaId');
@@ -597,7 +608,7 @@ class PenitipanBantuanController extends GetxController {
       // Debug: print semua data petugas desa yang sudah dimuat
       print('Data petugas desa yang sudah dimuat setelah reload:');
       petugasDesaCache.forEach((key, value) {
-        print('ID: $key, Nama: $value');
+        print('ID: $key, Nama: ${value['nama_lengkap']}');
       });
     } catch (e) {
       print('Error saat memuat ulang data petugas desa: $e');
@@ -643,15 +654,15 @@ class PenitipanBantuanController extends GetxController {
 
   Future<String?> tambahDonatur({
     required String nama,
-    required String telepon,
+    required String noHp,
     String? alamat,
     String? email,
     String? jenis,
   }) async {
     try {
       final donaturData = {
-        'nama': nama,
-        'telepon': telepon,
+        'nama_lengkap': nama,
+        'no_hp': noHp,
         'alamat': alamat,
         'email': email,
         'jenis': jenis,
diff --git a/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart b/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart
index aad316c..eb31efb 100644
--- a/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/petugas_desa_controller.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:penyaluran_app/app/data/models/desa_model.dart';
 import 'package:penyaluran_app/app/data/models/user_model.dart';
+import 'package:penyaluran_app/app/data/models/petugas_desa_model.dart';
 import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
 import 'package:penyaluran_app/app/modules/petugas_desa/controllers/counter_service.dart';
 import 'package:penyaluran_app/app/services/supabase_service.dart';
@@ -49,9 +50,57 @@ class PetugasDesaController extends GetxController {
   // Variabel untuk pencarian dan filter
   final searchQuery = ''.obs;
 
-  UserModel? get user => _authController.user;
-  String get role => user?.role ?? 'PETUGASDESA';
-  String get nama => user?.name ?? 'Petugas Desa';
+  BaseUserModel? get user => _authController.baseUser;
+  String get role => user?.roleName ?? 'PETUGAS_DESA';
+
+  // Helper method untuk format role agar lebih rapi
+  String get formattedRole {
+    final roleText = role.toLowerCase();
+    if (roleText.contains('_')) {
+      return roleText
+          .split('_')
+          .map((word) =>
+              word.isNotEmpty ? word[0].toUpperCase() + word.substring(1) : '')
+          .join(' ');
+    }
+    return roleText.isNotEmpty
+        ? roleText[0].toUpperCase() + roleText.substring(1)
+        : 'Petugas Desa';
+  }
+
+  String get nama {
+    // 1. Coba ambil dari AuthController displayName yang paling lengkap
+    final authDisplayName = _authController.displayName;
+    if (authDisplayName != null &&
+        authDisplayName != 'Pengguna' &&
+        authDisplayName != user?.email) {
+      return authDisplayName;
+    }
+
+    // 2. Coba ambil dari roleData jika merupakan PetugasDesaModel
+    final userData = _authController.userData;
+    if (userData != null && userData.roleData is PetugasDesaModel) {
+      final petugasData = userData.roleData as PetugasDesaModel;
+      if (petugasData.namaLengkap != null &&
+          petugasData.namaLengkap!.isNotEmpty) {
+        return petugasData.namaLengkap!;
+      }
+    }
+
+    // 3. Coba ambil dari user.name
+    if (user?.name != null && user!.name!.isNotEmpty) {
+      return user!.name!;
+    }
+
+    // 4. Fallback ke nama dari userProfile
+    if (userProfile['name'] != null &&
+        userProfile['name'].toString().isNotEmpty) {
+      return userProfile['name'];
+    }
+
+    // 5. Default fallback
+    return 'Petugas Desa';
+  }
 
   // Getter untuk counter dari CounterService
   RxInt get jumlahNotifikasiBelumDibaca =>
@@ -64,6 +113,13 @@ class PetugasDesaController extends GetxController {
 
   // Getter untuk nama desa dari profil pengguna
   String get desa {
+    // Debug info
+    print('DEBUG: Memeriksa data desa...');
+    if (user != null) {
+      print('DEBUG: User ID: ${user!.id}, User email: ${user!.email}');
+      print('DEBUG: User desa: ${user!.desa}');
+    }
+
     // Prioritaskan model desa dari user
     if (user?.desa != null) {
       print('DEBUG: Menggunakan desa dari user model: ${user!.desa!.nama}');
@@ -77,9 +133,15 @@ class PetugasDesaController extends GetxController {
       return desaNama;
     }
 
+    // Jika masih tidak ada, coba dari desaModel
+    if (desaModel.value != null) {
+      print('DEBUG: Menggunakan desa dari desaModel: ${desaModel.value!.nama}');
+      return desaModel.value!.nama;
+    }
+
     // Fallback ke nilai default
     print('DEBUG: Menggunakan nilai default untuk desa');
-    return userProfile['desa_id'] != null ? 'Desa' : 'Desa';
+    return 'Desa';
   }
 
   @override
@@ -109,34 +171,76 @@ class PetugasDesaController extends GetxController {
   // Metode untuk memuat data profil pengguna dari cache
   Future<void> loadUserProfile() async {
     try {
-      // Jika user sudah ada di AuthController, tidak perlu mengambil data lagi
+      // Jika user sudah ada di AuthController, gunakan data yang ada
       if (user != null) {
         print('DEBUG: User ditemukan di AuthController: ${user!.email}');
         print('DEBUG: User desa: ${user!.desa?.nama}');
 
-        // Ambil data tambahan jika diperlukan, tapi gunakan cache
-        final profileData = await _supabaseService.getUserProfile();
-        if (profileData != null) {
-          print('DEBUG: Profile data ditemukan: ${profileData['name']}');
-          userProfile.value = profileData;
+        // Tidak perlu mengambil data tambahan jika user.desa sudah ada
+        if (user!.desa != null) {
+          print(
+              'DEBUG: Menggunakan desa dari AuthController: ${user!.desa!.nama}');
+          desaModel.value = user!.desa;
 
-          // Parse data desa jika ada
-          if (profileData['desa'] != null &&
-              profileData['desa'] is Map<String, dynamic>) {
+          // Perbarui userProfile untuk konsistensi
+          if (userProfile.isEmpty) {
+            userProfile.value = {
+              'name': user!.name ?? _authController.displayName,
+              'desa': user!.desa?.toJson(),
+            };
+          }
+
+          return; // Data sudah lengkap, tidak perlu fetch lagi
+        }
+
+        print(
+            'DEBUG: Data desa tidak ditemukan di AuthController, mencoba ambil dari cache');
+
+        // Jika tidak ada desa di AuthController, coba ambil dari userData roleData
+        final userData = _authController.userData;
+        if (userData != null) {
+          if (userData.roleData is PetugasDesaModel) {
+            final petugasData = userData.roleData as PetugasDesaModel;
+            if (petugasData.desa != null) {
+              print(
+                  'DEBUG: Menggunakan desa dari roleData: ${petugasData.desa!.nama}');
+              desaModel.value = petugasData.desa;
+
+              // Perbarui userProfile untuk konsistensi
+              userProfile.value = {
+                'name': petugasData.displayName,
+                'desa': petugasData.desa?.toJson(),
+              };
+
+              return; // Data sudah lengkap, tidak perlu fetch lagi
+            }
+          }
+        }
+
+        // Jika tidak ada di cache, ambil dari API hanya jika benar-benar diperlukan
+        print('DEBUG: Data desa tidak ditemukan di cache, mengambil dari API');
+        final baseProfile = await _supabaseService.getUserProfile();
+        if (baseProfile != null) {
+          userProfile.value = baseProfile;
+
+          if (baseProfile['desa'] != null &&
+              baseProfile['desa'] is Map<String, dynamic>) {
             try {
-              final desaData = profileData['desa'] as Map<String, dynamic>;
-              print('DEBUG: Desa data ditemukan: $desaData');
+              final desaData = baseProfile['desa'] as Map<String, dynamic>;
+              print('DEBUG: Desa data ditemukan dari API: $desaData');
+              desaModel.value = DesaModel.fromJson(desaData);
             } catch (e) {
               print('Error parsing desa data: $e');
             }
           } else {
-            print('DEBUG: Desa data tidak ditemukan atau bukan Map');
+            print('DEBUG: Desa data tidak ditemukan di API');
           }
         } else {
-          print('DEBUG: Profile data tidak ditemukan');
+          print('DEBUG: Profile data tidak ditemukan dari API');
         }
       } else {
-        print('DEBUG: User tidak ditemukan di AuthController');
+        print(
+            'DEBUG: User tidak ditemukan di AuthController, mungkin belum login');
       }
     } catch (e) {
       print('Error loading user profile: $e');
diff --git a/lib/app/modules/petugas_desa/controllers/petugas_desa_dashboard_controller.dart b/lib/app/modules/petugas_desa/controllers/petugas_desa_dashboard_controller.dart
index f261988..bc33795 100644
--- a/lib/app/modules/petugas_desa/controllers/petugas_desa_dashboard_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/petugas_desa_dashboard_controller.dart
@@ -27,7 +27,7 @@ class PetugasDesaDashboardController extends GetxController {
   // Controller untuk pencarian
   final TextEditingController searchController = TextEditingController();
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
   String get role => user?.role ?? 'PETUGASDESA';
   String get nama => user?.name ?? 'Petugas Desa';
 
diff --git a/lib/app/modules/petugas_desa/controllers/riwayat_pengaduan_controller.dart b/lib/app/modules/petugas_desa/controllers/riwayat_pengaduan_controller.dart
index 34bf314..3179264 100644
--- a/lib/app/modules/petugas_desa/controllers/riwayat_pengaduan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/riwayat_pengaduan_controller.dart
@@ -17,7 +17,7 @@ class RiwayatPengaduanController extends GetxController {
   // Controller untuk pencarian
   final TextEditingController searchController = TextEditingController();
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   @override
   void onInit() {
diff --git a/lib/app/modules/petugas_desa/controllers/stok_bantuan_controller.dart b/lib/app/modules/petugas_desa/controllers/stok_bantuan_controller.dart
index 533b587..2fcaa30 100644
--- a/lib/app/modules/petugas_desa/controllers/stok_bantuan_controller.dart
+++ b/lib/app/modules/petugas_desa/controllers/stok_bantuan_controller.dart
@@ -36,7 +36,7 @@ class StokBantuanController extends GetxController {
   // Tambahkan properti untuk waktu terakhir update
   Rx<DateTime> lastUpdateTime = DateTime.now().obs;
 
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
 
   @override
   void onInit() {
diff --git a/lib/app/modules/petugas_desa/views/detail_donatur_view.dart b/lib/app/modules/petugas_desa/views/detail_donatur_view.dart
index b75ad9f..3c489fc 100644
--- a/lib/app/modules/petugas_desa/views/detail_donatur_view.dart
+++ b/lib/app/modules/petugas_desa/views/detail_donatur_view.dart
@@ -198,7 +198,7 @@ class DetailDonaturView extends GetView<DonaturController> {
                       donatur.alamat ?? 'Tidak ada alamat'),
                   const SizedBox(height: 8),
                   _buildInfoItem(Icons.phone, 'Telepon',
-                      donatur.telepon ?? 'Tidak ada telepon'),
+                      donatur.noHp ?? 'Tidak ada telepon'),
                   const SizedBox(height: 8),
                   _buildInfoItem(
                       Icons.email, 'Email', donatur.email ?? 'Tidak ada email'),
diff --git a/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart b/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart
index 6af3e60..eef94e4 100644
--- a/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart
+++ b/lib/app/modules/petugas_desa/views/detail_penyaluran_page.dart
@@ -1223,8 +1223,11 @@ class DetailPenyaluranPage extends StatelessWidget {
                       const Divider(height: 24),
                       if (warga != null) ...[
                         _buildInfoRow('NIK', warga['nik'] ?? '-'),
-                        _buildInfoRow('Alamat Lengkap',
-                            '${warga['alamat'] ?? '-'} Desa ${warga['desa'] ?? '-'} Kecamatan ${warga['kecamatan'] ?? '-'} Kabupaten ${warga['kabupaten'] ?? '-'} Provinsi ${warga['provinsi'] ?? '-'}'),
+                        _buildInfoRow('Alamat', warga['alamat'] ?? '-'),
+                        _buildInfoRow('Desa', warga['desa'] ?? '-'),
+                        _buildInfoRow('Kecamatan', warga['kecamatan'] ?? '-'),
+                        _buildInfoRow('Kabupaten', warga['kabupaten'] ?? '-'),
+                        _buildInfoRow('Provinsi', warga['provinsi'] ?? '-'),
                         _buildInfoRow(
                             'Jenis Kelamin', warga['jenis_kelamin'] ?? '-'),
                         _buildInfoRow('No. Telepon', warga['no_hp'] ?? '-'),
diff --git a/lib/app/modules/petugas_desa/views/penitipan_view.dart b/lib/app/modules/petugas_desa/views/penitipan_view.dart
index 02be88d..4111ffc 100644
--- a/lib/app/modules/petugas_desa/views/penitipan_view.dart
+++ b/lib/app/modules/petugas_desa/views/penitipan_view.dart
@@ -918,9 +918,8 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
                                         style: const TextStyle(
                                             fontWeight: FontWeight.bold),
                                       ),
-                                      if (selectedDonatur.value!.telepon !=
-                                          null)
-                                        Text(selectedDonatur.value!.telepon!),
+                                      if (selectedDonatur.value!.noHp != null)
+                                        Text(selectedDonatur.value!.noHp!),
                                     ],
                                   ),
                                 ),
@@ -984,9 +983,9 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
                                   return ListTile(
                                     title:
                                         Text(donatur.nama ?? 'Tidak ada nama'),
-                                    subtitle: donatur.telepon != null
-                                        ? Text(donatur.telepon!)
-                                        : null,
+                                    subtitle: donatur.noHp != null
+                                        ? Text(donatur.noHp!)
+                                        : const Text('Tidak ada nomor telepon'),
                                     dense: true,
                                     onTap: () {
                                       selectedDonatur.value = donatur;
@@ -1300,7 +1299,7 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
       BuildContext context, Function(String) onDonaturAdded) {
     final formKey = GlobalKey<FormState>();
     final TextEditingController namaController = TextEditingController();
-    final TextEditingController teleponController = TextEditingController();
+    final TextEditingController noHpController = TextEditingController();
     final TextEditingController alamatController = TextEditingController();
     final TextEditingController emailController = TextEditingController();
     final TextEditingController jenisController = TextEditingController();
@@ -1352,24 +1351,24 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
 
                   // Telepon
                   Text(
-                    'Nomor Telepon',
+                    'Nomor HP',
                     style: Theme.of(context).textTheme.titleSmall,
                   ),
                   const SizedBox(height: 8),
                   TextFormField(
-                    controller: teleponController,
+                    controller: noHpController,
                     keyboardType: TextInputType.phone,
                     decoration: InputDecoration(
                       border: OutlineInputBorder(
                         borderRadius: BorderRadius.circular(8),
                       ),
-                      hintText: 'Masukkan nomor telepon',
+                      hintText: 'Masukkan nomor HP',
                       contentPadding: const EdgeInsets.symmetric(
                           horizontal: 12, vertical: 8),
                     ),
                     validator: (value) {
                       if (value == null || value.isEmpty) {
-                        return 'Nomor telepon harus diisi';
+                        return 'Nomor HP harus diisi';
                       }
                       return null;
                     },
@@ -1396,24 +1395,16 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
                         : jenisController.text,
                     items: const [
                       DropdownMenuItem<String>(
-                        value: 'Perorangan',
-                        child: Text('Perorangan'),
+                        value: 'Individu',
+                        child: Text('Individu'),
                       ),
                       DropdownMenuItem<String>(
                         value: 'Perusahaan',
                         child: Text('Perusahaan'),
                       ),
                       DropdownMenuItem<String>(
-                        value: 'Lembaga',
-                        child: Text('Lembaga'),
-                      ),
-                      DropdownMenuItem<String>(
-                        value: 'Komunitas',
-                        child: Text('Komunitas'),
-                      ),
-                      DropdownMenuItem<String>(
-                        value: 'Lainnya',
-                        child: Text('Lainnya'),
+                        value: 'Organisasi',
+                        child: Text('Organisasi'),
                       ),
                     ],
                     onChanged: (value) {
@@ -1478,7 +1469,7 @@ class PenitipanView extends GetView<PenitipanBantuanController> {
                           if (formKey.currentState!.validate()) {
                             final donaturId = await controller.tambahDonatur(
                               nama: namaController.text,
-                              telepon: teleponController.text,
+                              noHp: noHpController.text,
                               alamat: alamatController.text.isEmpty
                                   ? null
                                   : alamatController.text,
diff --git a/lib/app/modules/petugas_desa/views/petugas_desa_view.dart b/lib/app/modules/petugas_desa/views/petugas_desa_view.dart
index f0c532b..19c30c2 100644
--- a/lib/app/modules/petugas_desa/views/petugas_desa_view.dart
+++ b/lib/app/modules/petugas_desa/views/petugas_desa_view.dart
@@ -151,7 +151,6 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
             return const DashboardView();
           case 1:
             return const PenyaluranView();
-
           case 2:
             return const PenitipanView();
           case 3:
@@ -182,22 +181,15 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
                 CircleAvatar(
                   radius: 30,
                   backgroundColor: Colors.white,
-                  backgroundImage: controller.user?.avatar != null &&
-                          controller.user!.avatar!.isNotEmpty
-                      ? NetworkImage(controller.user!.avatar!)
-                      : null,
-                  child: controller.user?.avatar == null ||
-                          controller.user!.avatar!.isEmpty
-                      ? const Icon(
-                          Icons.person,
-                          size: 40,
-                          color: AppTheme.primaryColor,
-                        )
-                      : null,
+                  child: const Icon(
+                    Icons.person,
+                    size: 40,
+                    color: AppTheme.primaryColor,
+                  ),
                 ),
                 const SizedBox(height: 10),
                 Text(
-                  controller.user?.name ?? 'Petugas Desa',
+                  controller.nama,
                   style: const TextStyle(
                     color: Colors.white,
                     fontSize: 18,
@@ -206,8 +198,8 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
                 ),
                 Text(
                   controller.user?.desa?.nama != null
-                      ? '${controller.user?.role} - ${controller.user!.desa!.nama}'
-                      : controller.user?.role ?? 'PETUGAS_DESA',
+                      ? '${controller.formattedRole} - ${controller.user!.desa!.nama}'
+                      : controller.formattedRole,
                   style: TextStyle(
                     color: Colors.white.withAlpha(200),
                     fontSize: 14,
@@ -251,9 +243,9 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
                     ? Badge(
                         label: Text(controller.jumlahDiproses.value.toString()),
                         backgroundColor: Colors.red,
-                        child: const Icon(Icons.support_outlined),
+                        child: const Icon(Icons.warning_amber_outlined),
                       )
-                    : const Icon(Icons.support_outlined),
+                    : const Icon(Icons.warning_amber_outlined),
                 title: const Text('Pengaduan'),
                 selected: controller.activeTabIndex.value == 3,
                 selectedColor: AppTheme.primaryColor,
@@ -272,6 +264,7 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
               controller.changeTab(4);
             },
           ),
+          const Divider(),
           ListTile(
             leading: const Icon(Icons.person_add_outlined),
             title: const Text('Kelola Penerima'),
@@ -296,7 +289,6 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
               Get.toNamed('/laporan-penyaluran');
             },
           ),
-          const Divider(),
           ListTile(
             leading: const Icon(Icons.person_outline),
             title: const Text('Profil'),
diff --git a/lib/app/modules/petugas_desa/views/riwayat_penitipan_view.dart b/lib/app/modules/petugas_desa/views/riwayat_penitipan_view.dart
index b17e109..f6ecc18 100644
--- a/lib/app/modules/petugas_desa/views/riwayat_penitipan_view.dart
+++ b/lib/app/modules/petugas_desa/views/riwayat_penitipan_view.dart
@@ -310,11 +310,15 @@ class RiwayatPenitipanView extends GetView<PenitipanBantuanController> {
                 if (item.status == 'TERVERIFIKASI' &&
                     item.petugasDesaId != null)
                   Expanded(
-                    child: _buildItemDetail(
-                      context,
-                      icon: Icons.person,
-                      label: 'Diverifikasi Oleh',
-                      value: controller.getPetugasDesaNama(item.petugasDesaId),
+                    child: GetBuilder<PenitipanBantuanController>(
+                      id: 'petugas_data',
+                      builder: (controller) => _buildItemDetail(
+                        context,
+                        icon: Icons.person,
+                        label: 'Diverifikasi Oleh',
+                        value:
+                            controller.getPetugasDesaNama(item.petugasDesaId),
+                      ),
                     ),
                   ),
               ],
diff --git a/lib/app/modules/profile/controllers/profile_controller.dart b/lib/app/modules/profile/controllers/profile_controller.dart
index 962055d..2d998c1 100644
--- a/lib/app/modules/profile/controllers/profile_controller.dart
+++ b/lib/app/modules/profile/controllers/profile_controller.dart
@@ -1,14 +1,17 @@
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:penyaluran_app/app/data/models/user_model.dart';
-import 'package:penyaluran_app/app/services/auth_service.dart';
+import 'package:penyaluran_app/app/services/supabase_service.dart';
+import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
 
 class ProfileController extends GetxController {
-  final AuthService _authService = Get.find<AuthService>();
+  final SupabaseService _supabaseService = Get.find<SupabaseService>();
+  final AuthController _authController = Get.find<AuthController>();
 
-  final Rx<User?> user = Rx<User?>(null);
+  final Rx<BaseUserModel?> user = Rx<BaseUserModel?>(null);
   final RxBool isLoading = true.obs;
   final RxBool isEditing = false.obs;
+  final Rx<Map<String, dynamic>?> roleData = Rx<Map<String, dynamic>?>(null);
 
   // Form controllers
   late TextEditingController nameController;
@@ -36,14 +39,23 @@ class ProfileController extends GetxController {
     isLoading.value = true;
     try {
       // Mendapatkan data user dari service
-      final userData = await _authService.getCurrentUser();
-      user.value = userData;
-
-      // Mengisi form controllers dengan data user
+      final userData = await _supabaseService.getUserProfile();
       if (userData != null) {
-        nameController.text = userData.name ?? '';
-        emailController.text = userData.email ?? '';
-        phoneController.text = userData.phone ?? '';
+        user.value = BaseUserModel.fromJson(userData);
+
+        // Mengisi form controllers dengan data user
+        nameController.text = user.value?.name ?? '';
+        emailController.text = user.value?.email ?? '';
+        // Catatan: BaseUserModel tidak memiliki properti phone
+        // Jika ada data role_data, simpan untuk ditampilkan
+        if (userData['role_data'] != null) {
+          roleData.value = userData['role_data'] as Map<String, dynamic>?;
+          // Jika role adalah warga, ambil no telepon dari role data
+          if (user.value?.role?.toLowerCase() == 'warga' &&
+              roleData.value?['no_hp'] != null) {
+            phoneController.text = roleData.value?['no_hp'] ?? '';
+          }
+        }
       }
     } catch (e) {
       Get.snackbar(
@@ -76,22 +88,45 @@ class ProfileController extends GetxController {
 
     isLoading.value = true;
     try {
-      // Update user data
-      final updatedUser = User(
-        id: user.value?.id,
-        name: nameController.text,
-        email: emailController.text,
-        phone: phoneController.text,
-        role: user.value?.role,
-        token: user.value?.token,
-      );
+      final userData = user.value;
+      if (userData == null) throw 'Data user tidak ditemukan';
 
-      // Panggil API untuk update profil
-      await _authService.updateProfile(updatedUser);
+      // Update data sesuai role
+      switch (userData.role?.toLowerCase() ?? 'unknown') {
+        case 'warga':
+          await _supabaseService.updateWargaProfile(
+            userId: userData.id,
+            namaLengkap: nameController.text,
+            noHp: phoneController.text,
+            email: emailController.text,
+          );
+          break;
+        case 'donatur':
+          await _supabaseService.updateDonaturProfile(
+            userId: userData.id,
+            nama: nameController.text,
+            noHp: phoneController.text,
+            email: emailController.text,
+          );
+          break;
+        case 'petugas_desa':
+          await _supabaseService.updatePetugasDesaProfile(
+            userId: userData.id,
+            nama: nameController.text,
+            noHp: phoneController.text,
+            email: emailController.text,
+          );
+          break;
+        default:
+          throw 'Role tidak valid';
+      }
 
-      // Refresh data
+      // Refresh data lokal
       await loadUserData();
 
+      // Refresh data di AuthController untuk menyebarkan perubahan ke seluruh aplikasi
+      await _authController.refreshUserData();
+
       // Keluar dari mode edit
       isEditing.value = false;
 
@@ -131,7 +166,7 @@ class ProfileController extends GetxController {
     isLoading.value = true;
     try {
       // Panggil API untuk ganti password
-      await _authService.changePassword(currentPassword, newPassword);
+      await _supabaseService.changePassword(currentPassword, newPassword);
 
       Get.back(); // Tutup dialog
 
diff --git a/lib/app/modules/profile/views/profile_view.dart b/lib/app/modules/profile/views/profile_view.dart
index 4fc149b..6028d49 100644
--- a/lib/app/modules/profile/views/profile_view.dart
+++ b/lib/app/modules/profile/views/profile_view.dart
@@ -87,6 +87,7 @@ class ProfileView extends GetView<ProfileController> {
   Widget _buildProfileForm() {
     return Obx(() {
       final isEditing = controller.isEditing.value;
+      final user = controller.user.value;
 
       return Column(
         crossAxisAlignment: CrossAxisAlignment.start,
@@ -119,7 +120,7 @@ class ProfileView extends GetView<ProfileController> {
               labelText: 'Email',
               border: OutlineInputBorder(),
               prefixIcon: Icon(Icons.email),
-              enabled: isEditing,
+              enabled: false, // Email tidak bisa diubah
             ),
             keyboardType: TextInputType.emailAddress,
           ),
@@ -136,6 +137,113 @@ class ProfileView extends GetView<ProfileController> {
             ),
             keyboardType: TextInputType.phone,
           ),
+          const SizedBox(height: 16),
+
+          // Informasi tambahan sesuai role
+          if (user != null) ...[
+            if (user.role?.toLowerCase() == 'warga') ...[
+              const SizedBox(height: 24),
+              const Text(
+                'Informasi Warga',
+                style: TextStyle(
+                  fontSize: 18,
+                  fontWeight: FontWeight.bold,
+                ),
+              ),
+              const SizedBox(height: 16),
+              Obx(() {
+                final roleData = controller.roleData.value;
+                return Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    _buildInfoRow(
+                        Icons.perm_identity, 'NIK', roleData?['nik'] ?? '-'),
+                    const SizedBox(height: 8),
+                    _buildInfoRow(Icons.wc, 'Jenis Kelamin',
+                        roleData?['jenis_kelamin'] ?? '-'),
+                    const SizedBox(height: 8),
+                    _buildInfoRow(
+                        Icons.home, 'Alamat', roleData?['alamat'] ?? '-'),
+                    if (user.desa != null) ...[
+                      const SizedBox(height: 8),
+                      _buildInfoRow(
+                          Icons.location_city, 'Desa', user.desa!.nama),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Kecamatan',
+                          user.desa!.kecamatan ?? ''),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Kabupaten',
+                          user.desa!.kabupaten ?? ''),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Provinsi',
+                          user.desa!.provinsi ?? ''),
+                    ],
+                  ],
+                );
+              }),
+            ],
+            if (user.role?.toLowerCase() == 'donatur') ...[
+              const SizedBox(height: 24),
+              const Text(
+                'Informasi Donatur',
+                style: TextStyle(
+                  fontSize: 18,
+                  fontWeight: FontWeight.bold,
+                ),
+              ),
+              const SizedBox(height: 16),
+              Obx(() {
+                final roleData = controller.roleData.value;
+                return Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    _buildInfoRow(Icons.business, 'Instansi',
+                        roleData?['instansi'] ?? '-'),
+                    const SizedBox(height: 8),
+                    _buildInfoRow(
+                        Icons.work, 'Jabatan', roleData?['jabatan'] ?? '-'),
+                  ],
+                );
+              }),
+            ],
+            if (user.role?.toLowerCase() == 'petugas_desa') ...[
+              const SizedBox(height: 24),
+              const Text(
+                'Informasi Petugas Desa',
+                style: TextStyle(
+                  fontSize: 18,
+                  fontWeight: FontWeight.bold,
+                ),
+              ),
+              const SizedBox(height: 16),
+              Obx(() {
+                final roleData = controller.roleData.value;
+                return Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    _buildInfoRow(Icons.badge, 'NIP', roleData?['nip'] ?? '-'),
+                    const SizedBox(height: 8),
+                    _buildInfoRow(
+                        Icons.work, 'Jabatan', roleData?['jabatan'] ?? '-'),
+                    if (user.desa != null) ...[
+                      const SizedBox(height: 8),
+                      _buildInfoRow(
+                          Icons.location_city, 'Desa', user.desa!.nama),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Kecamatan',
+                          user.desa!.kecamatan ?? ''),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Kabupaten',
+                          user.desa!.kabupaten ?? ''),
+                      const SizedBox(height: 8),
+                      _buildInfoRow(Icons.location_on, 'Provinsi',
+                          user.desa!.provinsi ?? ''),
+                    ],
+                  ],
+                );
+              }),
+            ],
+          ],
         ],
       );
     });
@@ -230,4 +338,23 @@ class ProfileView extends GetView<ProfileController> {
       ),
     );
   }
+
+  Widget _buildInfoRow(IconData icon, String label, String value) {
+    return Row(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Icon(icon, size: 18, color: Colors.grey[700]),
+        const SizedBox(width: 8),
+        Expanded(
+          child: Text(
+            '$label: $value',
+            style: TextStyle(
+              fontSize: 14,
+              color: Colors.grey[700],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
 }
diff --git a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
index 91f899f..30cde09 100644
--- a/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
+++ b/lib/app/modules/warga/controllers/warga_dashboard_controller.dart
@@ -11,7 +11,7 @@ class WargaDashboardController extends GetxController {
   final AuthController _authController = Get.find<AuthController>();
   final SupabaseService _supabaseService = SupabaseService.to;
 
-  final Rx<UserModel?> currentUser = Rx<UserModel?>(null);
+  final Rx<BaseUserModel?> currentUser = Rx<BaseUserModel?>(null);
 
   // Indeks tab yang aktif di bottom navigation bar
   final RxInt activeTabIndex = 0.obs;
@@ -41,9 +41,18 @@ class WargaDashboardController extends GetxController {
   final RxInt jumlahNotifikasiBelumDibaca = 0.obs;
 
   // Getter untuk data user
-  UserModel? get user => _authController.user;
+  BaseUserModel? get user => _authController.baseUser;
   String get role => user?.role ?? 'WARGA';
-  String get nama => user?.name ?? 'Warga';
+  String get nama {
+    // Gunakan namaLengkap dari roleData jika tersedia
+    if (_authController.isWarga && _authController.roleData != null) {
+      return _authController.roleData.namaLengkap ??
+          _authController.displayName;
+    }
+    // Gunakan displayName dari AuthController
+    return _authController.displayName;
+  }
+
   String? get desa => user?.desa?.nama;
 
   @override
@@ -54,7 +63,30 @@ class WargaDashboardController extends GetxController {
   }
 
   void loadUserData() {
-    currentUser.value = _authController.user;
+    currentUser.value = _authController.baseUser;
+
+    // Tambahkan log debugging
+    print('DEBUG WARGA: Memuat data user dari AuthController');
+    print('DEBUG WARGA: baseUser: ${_authController.baseUser}');
+    print('DEBUG WARGA: roleData: ${_authController.roleData}');
+    print('DEBUG WARGA: nama yang akan ditampilkan: ${nama}');
+    print(
+        'DEBUG WARGA: displayName dari auth controller: ${_authController.displayName}');
+
+    if (_authController.userData != null) {
+      print(
+          'DEBUG WARGA: userData ada, role: ${_authController.userData!.baseUser.roleName}');
+
+      if (_authController.isWarga) {
+        print('DEBUG WARGA: User adalah warga');
+        var wargaData = _authController.roleData;
+        print('DEBUG WARGA: Data warga: ${wargaData?.namaLengkap}');
+      } else {
+        print('DEBUG WARGA: User bukan warga');
+      }
+    } else {
+      print('DEBUG WARGA: userData null');
+    }
   }
 
   void fetchData() async {
@@ -90,14 +122,8 @@ class WargaDashboardController extends GetxController {
       // Reset data terlebih dahulu untuk memastikan tidak ada data lama yang tersimpan
       penerimaPenyaluran.clear();
 
-      // Pertama, cari warga_id berdasarkan user_id
-      final wargaResponse = await _supabaseService.client
-          .from('warga')
-          .select('id')
-          .eq('user_id', user!.id)
-          .single();
-
-      final wargaId = wargaResponse['id'];
+      // Gunakan langsung ID pengguna sebagai warga_id
+      final wargaId = user!.id;
 
       // Ambil data penerima penyaluran dengan join ke warga, stok bantuan, dan penyaluran bantuan
       final response =
@@ -221,14 +247,8 @@ class WargaDashboardController extends GetxController {
   // Fungsi untuk mengambil data pengajuan kelayakan
   Future<void> fetchPengajuanKelayakan() async {
     try {
-      // Pertama, cari warga_id berdasarkan user_id
-      final wargaResponse = await _supabaseService.client
-          .from('warga')
-          .select('id')
-          .eq('user_id', user!.id)
-          .single();
-
-      final wargaId = wargaResponse['id'];
+      // Gunakan langsung ID pengguna sebagai warga_id
+      final wargaId = user!.id;
 
       final response = await _supabaseService.client
           .from('xx02_pengajuan_kelayakan_bantuan')
@@ -257,19 +277,17 @@ class WargaDashboardController extends GetxController {
       totalPengajuanDitolak.value =
           pengajuan.where((p) => p.status == StatusKelayakan.DITOLAK).length;
     } catch (e) {
-      print('Error fetching pengajuan kelayakan: $e');
+      print('Error fetchPengajuanKelayakan: $e');
     }
   }
 
   // Fungsi untuk mengambil data pengaduan
   Future<void> fetchPengaduan() async {
     try {
-      final wargaData = await _supabaseService.getWargaByUserId();
-      if (wargaData == null) {
-        return;
-      }
+      // Gunakan langsung ID user dari AuthController, bukan getWargaByUserId()
+      String wargaId = user!.id;
+      print('DEBUG WARGA: Mengambil pengaduan untuk warga ID: $wargaId');
 
-      final String wargaId = wargaData['id'];
       final response = await _supabaseService
           .getPengaduanWargaWithPenerimaPenyaluran(wargaId);
 
@@ -287,15 +305,21 @@ class WargaDashboardController extends GetxController {
             .length;
         totalPengaduanSelesai.value =
             pengaduanList.where((p) => p.status == 'SELESAI').length;
+
+        print(
+            'DEBUG WARGA: Berhasil mendapatkan ${pengaduanList.length} pengaduan');
+      } else {
+        print('DEBUG WARGA: Tidak ada pengaduan yang ditemukan');
       }
     } catch (e) {
-      print('Error fetching pengaduan: $e');
+      print('DEBUG WARGA: Error fetching pengaduan: $e');
     }
   }
 
   // Fungsi untuk mengambil data notifikasi
   Future<void> fetchNotifikasi() async {
     try {
+      // Notifikasi masih menggunakan user_id karena tabelnya terpisah
       final response = await _supabaseService.client
           .from('notifikasi')
           .select('*')
@@ -429,13 +453,8 @@ class WargaDashboardController extends GetxController {
     try {
       isLoading.value = true;
 
-      // Cari warga_id berdasarkan user_id
-      final wargaData = await _supabaseService.getWargaByUserId();
-      if (wargaData == null) {
-        throw Exception('Data warga tidak ditemukan');
-      }
-
-      final String wargaId = wargaData['id'];
+      // Gunakan langsung ID pengguna sebagai warga_id
+      final String wargaId = user!.id;
 
       // Upload foto pengaduan jika ada
       List<String> fotoPengaduanUrls = [];
diff --git a/lib/app/services/auth_service.dart b/lib/app/services/auth_service.dart
index 5fe8c92..3d8e220 100644
--- a/lib/app/services/auth_service.dart
+++ b/lib/app/services/auth_service.dart
@@ -7,15 +7,17 @@ class AuthService extends GetxService {
   final Dio _dio = Dio();
   final FlutterSecureStorage _storage = const FlutterSecureStorage();
 
-  final Rx<User?> currentUser = Rx<User?>(null);
+  final Rx<BaseUserModel?> currentUser = Rx<BaseUserModel?>(null);
+  String? _token;
 
   // Mendapatkan data user saat ini
-  Future<User?> getCurrentUser() async {
+  Future<BaseUserModel?> getCurrentUser() async {
     try {
       // Implementasi untuk mendapatkan data user dari API atau local storage
       // Contoh implementasi sederhana:
       final token = await _storage.read(key: 'token');
       if (token == null) return null;
+      _token = token;
 
       final response = await _dio.get(
         '/api/user/profile',
@@ -27,7 +29,7 @@ class AuthService extends GetxService {
       );
 
       if (response.statusCode == 200) {
-        final user = User.fromJson(response.data['data']);
+        final user = BaseUserModel.fromJson(response.data['data']);
         currentUser.value = user;
         return user;
       }
@@ -40,7 +42,7 @@ class AuthService extends GetxService {
   }
 
   // Update profil user
-  Future<bool> updateProfile(User user) async {
+  Future<bool> updateProfile(BaseUserModel user) async {
     try {
       final token = await _storage.read(key: 'token');
       if (token == null) return false;
@@ -50,7 +52,7 @@ class AuthService extends GetxService {
         data: {
           'name': user.name,
           'email': user.email,
-          'phone': user.phone,
+          // 'phone' tidak tersedia di BaseUserModel, jadi kita hilangkan atau gunakan parameter lain
         },
         options: Options(
           headers: {
@@ -100,7 +102,7 @@ class AuthService extends GetxService {
   }
 
   // Login
-  Future<User?> login(String email, String password) async {
+  Future<BaseUserModel?> login(String email, String password) async {
     try {
       final response = await _dio.post(
         '/api/auth/login',
@@ -111,11 +113,13 @@ class AuthService extends GetxService {
       );
 
       if (response.statusCode == 200) {
-        final user = User.fromJson(response.data['data']);
+        final user = BaseUserModel.fromJson(response.data['data']);
 
-        // Simpan token
-        if (user.token != null) {
-          await _storage.write(key: 'token', value: user.token);
+        // Simpan token yang datang dari respons
+        if (response.data['token'] != null) {
+          final token = response.data['token'].toString();
+          await _storage.write(key: 'token', value: token);
+          _token = token;
         }
 
         currentUser.value = user;
@@ -148,6 +152,7 @@ class AuthService extends GetxService {
     } finally {
       // Hapus token dan user data
       await _storage.delete(key: 'token');
+      _token = null;
       currentUser.value = null;
 
       // Navigasi ke halaman login
@@ -155,6 +160,12 @@ class AuthService extends GetxService {
     }
   }
 
+  // Mendapatkan token autentikasi
+  Future<String?> getToken() async {
+    if (_token != null) return _token;
+    return await _storage.read(key: 'token');
+  }
+
   // Inisialisasi service
   Future<AuthService> init() async {
     // Coba mendapatkan user saat ini
diff --git a/lib/app/services/supabase_service.dart b/lib/app/services/supabase_service.dart
index 5305c65..14ecb6c 100644
--- a/lib/app/services/supabase_service.dart
+++ b/lib/app/services/supabase_service.dart
@@ -1,4 +1,8 @@
 import 'package:get/get.dart';
+import 'package:penyaluran_app/app/data/models/donatur_model.dart';
+import 'package:penyaluran_app/app/data/models/petugas_desa_model.dart';
+import 'package:penyaluran_app/app/data/models/user_model.dart';
+import 'package:penyaluran_app/app/data/models/warga_model.dart';
 import 'package:supabase_flutter/supabase_flutter.dart';
 import 'dart:io';
 
@@ -73,21 +77,6 @@ class SupabaseService extends GetxService {
     );
   }
 
-  // Metode untuk login
-  Future<AuthResponse> signIn(String email, String password) async {
-    final response = await client.auth.signInWithPassword(
-      email: email,
-      password: password,
-    );
-
-    if (response.user != null) {
-      _isSessionInitialized = true;
-      print('DEBUG: Login berhasil, sesi diinisialisasi');
-    }
-
-    return response;
-  }
-
   // Metode untuk logout
   Future<void> signOut() async {
     _cachedUserProfile = null; // Hapus cache saat logout
@@ -122,45 +111,301 @@ class SupabaseService extends GetxService {
     return false;
   }
 
-  // Metode untuk mendapatkan profil pengguna
-  Future<Map<String, dynamic>?> getUserProfile() async {
+  // Metode untuk mendapatkan profil pengguna dasar
+  Future<BaseUserModel?> getBaseUserProfile() async {
     final user = currentUser;
     if (user == null) return null;
 
     try {
-      // Gunakan cache jika tersedia
-      if (_cachedUserProfile != null && _cachedUserProfile!['id'] == user.id) {
-        print('Menggunakan data profil dari cache');
+      // Gunakan auth.getUser() daripada mengakses tabel auth.users
+      final userData = await client.auth.getUser();
+
+      print('userData: ${userData.user}');
+
+      if (userData.user == null) {
+        print('Tidak ada data user ditemukan');
+        return null;
+      }
+
+      // Dapatkan role dari tabel khusus roles jika diperlukan
+      String roleName = 'warga'; // default
+      if (userData.user!.userMetadata?['role_id'] != null) {
+        try {
+          final roleResponse = await client
+              .from('roles')
+              .select('role_name')
+              .eq('id', userData.user!.userMetadata!['role_id'])
+              .maybeSingle();
+
+          print('roleResponse: $roleResponse');
+
+          if (roleResponse != null) {
+            roleName = roleResponse['role_name'];
+          }
+        } catch (e) {
+          print('Error saat mengambil role: $e');
+          // Lanjutkan dengan role default jika gagal
+        }
+      }
+
+      // Gabungkan data user dan role
+      Map<String, dynamic> combinedData = {
+        'id': userData.user!.id,
+        'email': userData.user!.email,
+        'created_at': userData.user!.createdAt,
+        'updated_at': userData.user!.updatedAt,
+        'role_id': userData.user!.userMetadata?['role_id'],
+        'roles': {'role_name': roleName}
+      };
+
+      return BaseUserModel.fromJson(combinedData);
+    } catch (e) {
+      print('Error pada getBaseUserProfile: $e');
+      return null;
+    }
+  }
+
+  // Metode untuk mendapatkan profil pengguna dengan data lengkap
+  Future<Map<String, dynamic>?> getUserProfile() async {
+    try {
+      // Jika cache profil tersedia, gunakan
+      if (_cachedUserProfile != null) {
         return _cachedUserProfile;
       }
 
-      final response = await client
-          .from('user_profile')
-          .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
-          .eq('id', user.id)
-          .maybeSingle();
-      print('response: $response');
-
-      // Simpan ke cache
-      _cachedUserProfile = response;
-
-      // Log untuk debugging
-      if (response != null && response['desa'] != null) {
-        print('Desa data: ${response['desa']}');
-        print('Desa type: ${response['desa'].runtimeType}');
+      // Jika tidak ada cache, ambil dari database
+      final user = currentUser;
+      if (user == null) {
+        print('DEBUG: Tidak ada user yang login');
+        return null;
       }
 
-      return response;
+      final userId = user.id;
+
+      // Debug info
+      print('DEBUG: Mengambil data user profile untuk ID: $userId');
+
+      // Ambil data role dari database
+      final roleResponse = await client
+          .from('users_with_roles')
+          .select('role_name')
+          .eq('id', userId)
+          .maybeSingle();
+
+      if (roleResponse == null) {
+        print('DEBUG: Tidak menemukan role untuk user ID: $userId');
+        return null;
+      }
+
+      final roleName = roleResponse['role_name'];
+      print('DEBUG: Role name: $roleName');
+
+      // Ambil data khusus untuk role tersebut
+      Map<String, dynamic>? roleData;
+      switch (roleName.toLowerCase()) {
+        case 'warga':
+          final wargaResponse = await client
+              .from('warga')
+              .select(
+                  '*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+              .eq('id', userId)
+              .maybeSingle();
+          roleData = wargaResponse;
+          break;
+        case 'petugas_desa':
+          final petugasResponse = await client
+              .from('petugas_desa')
+              .select(
+                  '*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+              .eq('id', userId)
+              .maybeSingle();
+          roleData = petugasResponse;
+          break;
+        case 'donatur':
+          final donaturResponse = await client
+              .from('donatur')
+              .select('*')
+              .eq('id', userId)
+              .maybeSingle();
+          roleData = donaturResponse;
+          break;
+        default:
+          print('DEBUG: Role tidak dikenali: $roleName');
+          return null;
+      }
+
+      if (roleData == null) {
+        print('DEBUG: Tidak menemukan data untuk role: $roleName');
+        return null;
+      }
+
+      // Siapkan data kombinasi dari Supabase Auth + data dari tabel role
+      final combinedData = {
+        'id': userId,
+        'email': user.email,
+        'role': roleName,
+        'created_at': user.createdAt,
+        'updated_at': user.updatedAt,
+        'role_data': roleData,
+      };
+
+      // Tambahkan nama dari data role jika ada berdasarkan role
+      switch (roleName.toLowerCase()) {
+        case 'warga':
+          if (roleData['nama_lengkap'] != null) {
+            combinedData['name'] = roleData['nama_lengkap'];
+          }
+          break;
+        case 'petugas_desa':
+        case 'donatur':
+          if (roleData['nama'] != null) {
+            combinedData['name'] = roleData['nama'];
+          }
+          break;
+      }
+
+      // Tambahkan data role-specific
+      if (roleData != null) {
+        combinedData['role_data'] = roleData;
+
+        // Tambahkan data desa jika ada
+        if (roleData['desa'] != null) {
+          combinedData['desa'] = roleData['desa'];
+        }
+
+        // Tambahkan nama dari data role jika ada
+        if (roleData['nama_lengkap'] != null) {
+          combinedData['name'] = roleData['nama_lengkap'];
+        }
+      }
+
+      // Cache profil untuk penggunaan berikutnya
+      _cachedUserProfile = combinedData;
+      print('combinedData: $combinedData');
+      return combinedData;
     } catch (e) {
       print('Error pada getUserProfile: $e');
       return null;
     }
   }
 
-  // Metode untuk mendapatkan role pengguna
-  Future<String?> getUserRole() async {
-    final profile = await getUserProfile();
-    return profile?['role'];
+  // Metode eksplisit untuk membersihkan cache profil
+  void clearUserProfileCache() {
+    print('DEBUG: Membersihkan cache profil pengguna');
+    _cachedUserProfile = null;
+  }
+
+  // Metode untuk mendapatkan data warga
+  Future<WargaModel?> getWargaProfile(String userId) async {
+    try {
+      final response = await client
+          .from('warga')
+          .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+          .eq('id', userId) // id di tabel warga = userId
+          .maybeSingle();
+
+      if (response == null) {
+        print('Data warga tidak ditemukan');
+        return null;
+      }
+
+      return WargaModel.fromJson(response);
+    } catch (e) {
+      print('Error pada getWargaProfile: $e');
+      return null;
+    }
+  }
+
+  // Metode untuk mendapatkan data donatur
+  Future<DonaturModel?> getDonaturProfile(String userId) async {
+    try {
+      final response = await client
+          .from('donatur')
+          .select('*')
+          .eq('id', userId) // id di tabel donatur = userId
+          .maybeSingle();
+
+      if (response == null) {
+        print('Data donatur tidak ditemukan');
+        return null;
+      }
+
+      return DonaturModel.fromJson(response);
+    } catch (e) {
+      print('Error pada getDonaturProfile: $e');
+      return null;
+    }
+  }
+
+  // Metode untuk mendapatkan data petugas desa
+  Future<PetugasDesaModel?> getPetugasDesaProfile(String userId) async {
+    try {
+      final response = await client
+          .from('petugas_desa')
+          .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
+          .eq('id', userId) // id di tabel petugas_desa = userId
+          .maybeSingle();
+
+      if (response == null) {
+        print('Data petugas desa tidak ditemukan');
+        return null;
+      }
+
+      return PetugasDesaModel.fromJson(response);
+    } catch (e) {
+      print('Error pada getPetugasDesaProfile: $e');
+      return null;
+    }
+  }
+
+  // Metode untuk mendapatkan data user lengkap berdasarkan role
+  // @deprecated Gunakan AuthProvider.getCurrentUser() sebagai gantinya
+  // Metode ini dipertahankan untuk kompatibilitas mundur
+  Future<UserData?> getUserData() async {
+    print(
+        'WARNING: Menggunakan metode getUserData() yang sudah deprecated. Gunakan AuthProvider.getCurrentUser() sebagai gantinya.');
+
+    final baseUser = await getBaseUserProfile();
+    if (baseUser == null) return null;
+
+    try {
+      switch (baseUser.roleName.toLowerCase()) {
+        case 'warga':
+          final wargaData = await getWargaProfile(baseUser.id);
+          if (wargaData != null) {
+            return UserData<WargaModel>(
+              baseUser: baseUser,
+              roleData: wargaData,
+            );
+          }
+          break;
+        case 'donatur':
+          final donaturData = await getDonaturProfile(baseUser.id);
+          if (donaturData != null) {
+            return UserData<DonaturModel>(
+              baseUser: baseUser,
+              roleData: donaturData,
+            );
+          }
+          break;
+        case 'petugas_desa':
+          final petugasDesaData = await getPetugasDesaProfile(baseUser.id);
+          if (petugasDesaData != null) {
+            return UserData<PetugasDesaModel>(
+              baseUser: baseUser,
+              roleData: petugasDesaData,
+            );
+          }
+          break;
+      }
+
+      // Jika data role-specific tidak ditemukan
+      print('Data spesifik tidak ditemukan untuk role: ${baseUser.roleName}');
+      return null;
+    } catch (e) {
+      print('Error pada getUserData: $e');
+      return null;
+    }
   }
 
   // ==================== PETUGAS DESA METHODS ====================
@@ -211,6 +456,7 @@ class SupabaseService extends GetxService {
   Future<List<Map<String, dynamic>>?> getNotifikasiBelumDibaca(
       String userId) async {
     try {
+      // Notifikasi masih menggunakan user_id karena tabelnya terpisah
       final response = await client
           .from('notifikasi')
           .select('*')
@@ -457,7 +703,7 @@ class SupabaseService extends GetxService {
     try {
       final response = await client
           .from('penitipan_bantuan')
-          .select('*, donatur:donatur_id(*), stok_bantuan:stok_bantuan_id(*)')
+          .select('*, donatur(*), stok_bantuan:stok_bantuan_id(*)')
           .order('tanggal_penitipan', ascending: false);
 
       return response;
@@ -472,7 +718,7 @@ class SupabaseService extends GetxService {
     try {
       final response = await client
           .from('penitipan_bantuan')
-          .select('*, donatur:donatur_id(*), stok_bantuan:stok_bantuan_id(*)')
+          .select('*, donatur(*), stok_bantuan:stok_bantuan_id(*)')
           .eq('status', 'TERVERIFIKASI')
           .order('tanggal_penitipan', ascending: false);
 
@@ -677,6 +923,12 @@ class SupabaseService extends GetxService {
   // Metode untuk menambahkan donatur baru
   Future<String?> tambahDonatur(Map<String, dynamic> donaturData) async {
     try {
+      // Pastikan field nama_lengkap ada di donaturData
+      if (donaturData.containsKey('nama')) {
+        donaturData['nama_lengkap'] = donaturData['nama'];
+        donaturData.remove('nama');
+      }
+
       final response =
           await client.from('donatur').insert(donaturData).select('id');
       if (response.isNotEmpty) {
@@ -798,8 +1050,8 @@ class SupabaseService extends GetxService {
           .from('tindakan_pengaduan')
           .select('''
             *,
-            petugas:petugas_id(id, nama, email),
-            verifikator:verifikator_id(id, nama, email)
+            petugas:petugas_id(id, nama_lengkap, nip),
+            verifikator:verifikator_id(id, nama_lengkap, nip)
           ''')
           .eq('pengaduan_id', pengaduanId)
           .order('created_at', ascending: false);
@@ -956,7 +1208,7 @@ class SupabaseService extends GetxService {
       final response = await client
           .from('warga')
           .select('*')
-          .eq('user_id', user.id)
+          .eq('id', user.id)
           .maybeSingle();
 
       return response;
@@ -981,8 +1233,27 @@ class SupabaseService extends GetxService {
       final user = currentUser;
       if (user == null) throw 'User tidak ditemukan';
 
+      // Dapatkan role_id untuk warga
+      final roleResponse = await client
+          .from('roles')
+          .select('id')
+          .eq('role_name', 'warga')
+          .single();
+
+      if (roleResponse == null) {
+        throw 'Role warga tidak ditemukan';
+      }
+
+      final roleId = roleResponse['id'];
+
+      // Update role_id di auth.users
+      await client
+          .from('auth.users')
+          .update({'role_id': roleId}).eq('id', user.id);
+
+      // Buat profil warga
       await client.from('warga').insert({
-        'user_id': user.id,
+        'id': user.id, // Gunakan id dari auth.users sebagai id di tabel warga
         'nik': nik,
         'nama_lengkap': namaLengkap,
         'jenis_kelamin': jenisKelamin,
@@ -995,15 +1266,111 @@ class SupabaseService extends GetxService {
         'created_at': DateTime.now().toIso8601String(),
         'updated_at': DateTime.now().toIso8601String(),
       });
+    } catch (e) {
+      print('Error creating warga profile: $e');
+      throw e.toString();
+    }
+  }
 
-      // Update user profile role
-      await client.from('user_profile').upsert({
-        'id': user.id,
-        'role': 'WARGA',
+  // Metode untuk membuat profil donatur
+  Future<void> createDonaturProfile({
+    required String nama_lengkap,
+    String? alamat,
+    String? noHp,
+    String? email,
+    String? jenis,
+    String? deskripsi,
+  }) async {
+    try {
+      final user = currentUser;
+      if (user == null) throw 'User tidak ditemukan';
+
+      // Dapatkan role_id untuk donatur
+      final roleResponse = await client
+          .from('roles')
+          .select('id')
+          .eq('role_name', 'donatur')
+          .single();
+
+      if (roleResponse == null) {
+        throw 'Role donatur tidak ditemukan';
+      }
+
+      final roleId = roleResponse['id'];
+
+      // Update role_id di auth.users
+      await client
+          .from('auth.users')
+          .update({'role_id': roleId}).eq('id', user.id);
+
+      // Buat profil donatur
+      await client.from('donatur').insert({
+        'id': user.id, // Gunakan id dari auth.users sebagai id di tabel donatur
+        'nama_lengkap': nama_lengkap,
+        'alamat': alamat,
+        'no_hp': noHp,
+        'email': email,
+        'jenis': jenis,
+        'deskripsi': deskripsi,
+        'status': 'AKTIF',
+        'created_at': DateTime.now().toIso8601String(),
         'updated_at': DateTime.now().toIso8601String(),
       });
     } catch (e) {
-      print('Error creating warga profile: $e');
+      print('Error creating donatur profile: $e');
+      throw e.toString();
+    }
+  }
+
+  // Metode untuk membuat profil petugas desa
+  Future<void> createPetugasDesaProfile({
+    required String nama_lengkap,
+    String? alamat,
+    String? noHp,
+    String? email,
+    String? jabatan,
+    String? nip,
+    required String desa_id,
+  }) async {
+    try {
+      final user = currentUser;
+      if (user == null) throw 'User tidak ditemukan';
+
+      // Dapatkan role_id untuk petugas desa
+      final roleResponse = await client
+          .from('roles')
+          .select('id')
+          .eq('role_name', 'petugas_desa')
+          .single();
+
+      if (roleResponse == null) {
+        throw 'Role petugas desa tidak ditemukan';
+      }
+
+      final roleId = roleResponse['id'];
+
+      // Update role_id di auth.users
+      await client
+          .from('auth.users')
+          .update({'role_id': roleId}).eq('id', user.id);
+
+      // Buat profil petugas desa
+      await client.from('petugas_desa').insert({
+        'id': user
+            .id, // Gunakan id dari auth.users sebagai id di tabel petugas_desa
+        'nama_lengkap': nama_lengkap,
+        'alamat': alamat,
+        'no_hp': noHp,
+        'email': email,
+        'jabatan': jabatan,
+        'nip': nip,
+        'desa_id': desa_id,
+        'status': 'AKTIF',
+        'created_at': DateTime.now().toIso8601String(),
+        'updated_at': DateTime.now().toIso8601String(),
+      });
+    } catch (e) {
+      print('Error creating petugas desa profile: $e');
       throw e.toString();
     }
   }
@@ -1015,6 +1382,7 @@ class SupabaseService extends GetxService {
       final user = currentUser;
       if (user == null) return [];
 
+      // Notifikasi masih menggunakan user_id karena tabelnya terpisah
       final query = unreadOnly
           ? client
               .from('notifikasi')
@@ -1054,19 +1422,17 @@ class SupabaseService extends GetxService {
     try {
       print('Mengambil data petugas desa dengan ID: $petugasDesaId');
 
-      // Coba ambil dari tabel user_profile dulu
+      // Gunakan tabel petugas_desa sebagai pengganti user_profile
       final response = await client
-          .from('user_profile')
-          .select('*')
+          .from('petugas_desa')
+          .select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
           .eq('id', petugasDesaId)
-          .eq('role', 'PETUGASDESA')
           .maybeSingle();
 
       print('Response: $response');
 
       if (response != null) {
-        print(
-            'Berhasil mendapatkan data petugas desa dari user_profile: $response');
+        print('Berhasil mendapatkan data petugas desa: $response');
         return response;
       }
 
@@ -1245,4 +1611,126 @@ class SupabaseService extends GetxService {
       return null;
     }
   }
+
+  // Metode untuk update profil warga
+  Future<void> updateWargaProfile({
+    required String userId,
+    required String namaLengkap,
+    String? noHp,
+    String? email,
+    String? alamat,
+    String? nik,
+    String? tempatLahir,
+    DateTime? tanggalLahir,
+    String? jenisKelamin,
+    String? agama,
+    String? kategoriEkonomi,
+  }) async {
+    try {
+      final data = {
+        'nama_lengkap': namaLengkap,
+        'updated_at': DateTime.now().toIso8601String(),
+      };
+
+      if (noHp != null) data['no_hp'] = noHp;
+      if (email != null) data['email'] = email;
+      if (alamat != null) data['alamat'] = alamat;
+      if (nik != null) data['nik'] = nik;
+      if (tempatLahir != null) data['tempat_lahir'] = tempatLahir;
+      if (tanggalLahir != null)
+        data['tanggal_lahir'] = tanggalLahir.toIso8601String();
+      if (jenisKelamin != null) data['jenis_kelamin'] = jenisKelamin;
+      if (agama != null) data['agama'] = agama;
+      if (kategoriEkonomi != null) data['kategori_ekonomi'] = kategoriEkonomi;
+
+      await client.from('warga').update(data).eq('id', userId);
+
+      // Hapus cache setelah update
+      clearUserProfileCache();
+    } catch (e) {
+      print('Error updating warga profile: $e');
+      throw e.toString();
+    }
+  }
+
+  // Metode untuk update profil donatur
+  Future<void> updateDonaturProfile({
+    required String userId,
+    required String nama,
+    String? alamat,
+    String? noHp,
+    String? email,
+    String? jenis,
+    String? instansi,
+    String? jabatan,
+  }) async {
+    try {
+      final data = {
+        'nama': nama,
+        'updated_at': DateTime.now().toIso8601String(),
+      };
+
+      if (alamat != null) data['alamat'] = alamat;
+      if (noHp != null) data['no_hp'] = noHp;
+      if (email != null) data['email'] = email;
+      if (jenis != null) data['jenis'] = jenis;
+      if (instansi != null) data['instansi'] = instansi;
+      if (jabatan != null) data['jabatan'] = jabatan;
+
+      await client.from('donatur').update(data).eq('id', userId);
+
+      // Hapus cache setelah update
+      clearUserProfileCache();
+    } catch (e) {
+      print('Error updating donatur profile: $e');
+      throw e.toString();
+    }
+  }
+
+  // Metode untuk update profil petugas desa
+  Future<void> updatePetugasDesaProfile({
+    required String userId,
+    required String nama,
+    String? alamat,
+    String? noHp,
+    String? email,
+    String? nip,
+    String? jabatan,
+  }) async {
+    try {
+      final data = {
+        'nama': nama,
+        'updated_at': DateTime.now().toIso8601String(),
+      };
+
+      if (alamat != null) data['alamat'] = alamat;
+      if (noHp != null) data['no_hp'] = noHp;
+      if (email != null) data['email'] = email;
+      if (nip != null) data['nip'] = nip;
+      if (jabatan != null) data['jabatan'] = jabatan;
+
+      await client.from('petugas_desa').update(data).eq('id', userId);
+
+      // Hapus cache setelah update
+      clearUserProfileCache();
+    } catch (e) {
+      print('Error updating petugas desa profile: $e');
+      throw e.toString();
+    }
+  }
+
+  // Metode untuk ganti password
+  Future<void> changePassword(
+      String currentPassword, String newPassword) async {
+    try {
+      await client.auth.updateUser(
+        UserAttributes(
+          password: newPassword,
+        ),
+      );
+    } catch (e) {
+      print('Error changing password: $e');
+      throw e.toString();
+    }
+  }
 }
