Perbarui tampilan DetailPengaduanView dan PengaduanView untuk meningkatkan konsistensi dan pengalaman pengguna. Tambahkan konstanta warna untuk status pengaduan dan modifikasi penggunaan warna di seluruh tampilan. Ganti metode filter dengan PopupMenuButton untuk kemudahan akses dan tambahkan informasi waktu terakhir update pada PengaduanView.
This commit is contained in:
@ -2,27 +2,27 @@ C/C++ Structured LogO
|
|||||||
M
|
M
|
||||||
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
||||||
A
|
A
|
||||||
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
|
|
||||||
}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\additional_project_files.txt <08><><EFBFBD><EFBFBD><EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\additional_project_files.txt <08><>ס<EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
||||||
|
|
|
|
||||||
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build.json <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build.json <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build_mini.json <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2p
|
D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\android_gradle_build_mini.json <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2p
|
||||||
n
|
n
|
||||||
lD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja <08><><EFBFBD><EFBFBD><EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
lD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja <08><>ס<EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
||||||
r
|
r
|
||||||
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja.txt <08><><EFBFBD><EFBFBD><EFBFBD>2y
|
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build.ninja.txt <08><>ס<EFBFBD>2y
|
||||||
w
|
w
|
||||||
uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build_file_index.txt <08><><EFBFBD><EFBFBD><EFBFBD>2
|
uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\build_file_index.txt <08><>ס<EFBFBD>2
|
||||||
K <20><><EFBFBD><EFBFBD><EFBFBD>2z
|
K <20><><EFBFBD><EFBFBD><EFBFBD>2z
|
||||||
x
|
x
|
||||||
vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json <08><>ס<EFBFBD>2 ~
|
vD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json <08><>ס<EFBFBD>2 ~
|
||||||
|
|
|
|
||||||
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json.bin <08><>ס<EFBFBD>2
|
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\compile_commands.json.bin <08><>ס<EFBFBD>2
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\metadata_generation_command.txt <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2w
|
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\metadata_generation_command.txt <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2w
|
||||||
u
|
u
|
||||||
sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\prefab_config.json <08><>ס<EFBFBD>2
|
sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\arm64-v8a\prefab_config.json <08><>ס<EFBFBD>2
|
||||||
( <20><><EFBFBD><EFBFBD><EFBFBD>2|
|
( <20><><EFBFBD><EFBFBD><EFBFBD>2|
|
@ -2,27 +2,27 @@ C/C++ Structured LogO
|
|||||||
M
|
M
|
||||||
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
||||||
A
|
A
|
||||||
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint κ<EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint ɠס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\additional_project_files.txt κ<EFBFBD><EFBFBD><EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\additional_project_files.txt ɠס<EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
~
|
~
|
||||||
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build.json κ<EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build.json ɠס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build_mini.json κ<EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2r
|
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\android_gradle_build_mini.json ʠס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2r
|
||||||
p
|
p
|
||||||
nD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja κ<EFBFBD><EFBFBD><EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2v
|
nD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja ʠס<EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2v
|
||||||
t
|
t
|
||||||
rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja.txt κ<EFBFBD><EFBFBD><EFBFBD>2{
|
rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build.ninja.txt ʠס<EFBFBD>2{
|
||||||
y
|
y
|
||||||
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build_file_index.txt κ<EFBFBD><EFBFBD><EFBFBD>2
|
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\build_file_index.txt ʠס<EFBFBD>2
|
||||||
K <20><><EFBFBD><EFBFBD><EFBFBD>2|
|
K <20><><EFBFBD><EFBFBD><EFBFBD>2|
|
||||||
z
|
z
|
||||||
xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json ʠס<CAA0>2 <09>
|
xD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json ʠס<CAA0>2 <09>
|
||||||
~
|
~
|
||||||
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json.bin ʠס<CAA0>2
|
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\compile_commands.json.bin ʠס<CAA0>2
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\metadata_generation_command.txt ʠס<CAA0>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2y
|
<EFBFBD>D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\metadata_generation_command.txt ʠס<CAA0>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2y
|
||||||
w
|
w
|
||||||
uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\prefab_config.json ʠס<CAA0>2
|
uD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\armeabi-v7a\prefab_config.json ʠס<CAA0>2
|
||||||
( <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
( <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
@ -2,27 +2,27 @@ C/C++ Structured LogO
|
|||||||
M
|
M
|
||||||
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
||||||
A
|
A
|
||||||
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2{
|
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2{
|
||||||
y
|
y
|
||||||
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\additional_project_files.txt <08><><EFBFBD><EFBFBD><EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2x
|
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\additional_project_files.txt <08><>ס<EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2x
|
||||||
v
|
v
|
||||||
tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build.json <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2}
|
tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build.json <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2}
|
||||||
{
|
{
|
||||||
yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build_mini.json <08><><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2j
|
yD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\android_gradle_build_mini.json <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2j
|
||||||
h
|
h
|
||||||
fD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja <08><><EFBFBD><EFBFBD><EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2n
|
fD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja <08><>ס<EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2n
|
||||||
l
|
l
|
||||||
jD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja.txt <08><><EFBFBD><EFBFBD><EFBFBD>2s
|
jD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build.ninja.txt <08><>ס<EFBFBD>2s
|
||||||
q
|
q
|
||||||
oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build_file_index.txt <08><><EFBFBD><EFBFBD><EFBFBD>2
|
oD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\build_file_index.txt <08><>ס<EFBFBD>2
|
||||||
K <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
K <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
||||||
r
|
r
|
||||||
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json <08><>ס<EFBFBD>2 x
|
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json <08><>ס<EFBFBD>2 x
|
||||||
v
|
v
|
||||||
tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json.bin <08><>ס<EFBFBD>2
|
tD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\compile_commands.json.bin <08><>ס<EFBFBD>2
|
||||||
~
|
~
|
||||||
|
|
|
|
||||||
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\metadata_generation_command.txt <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2q
|
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\metadata_generation_command.txt <08><>ס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2q
|
||||||
o
|
o
|
||||||
mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\prefab_config.json <08><>ס<EFBFBD>2
|
mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86\prefab_config.json <08><>ס<EFBFBD>2
|
||||||
( <20><><EFBFBD><EFBFBD><EFBFBD>2v
|
( <20><><EFBFBD><EFBFBD><EFBFBD>2v
|
@ -2,27 +2,27 @@ C/C++ Structured LogO
|
|||||||
M
|
M
|
||||||
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
KC:\dev\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txtC
|
||||||
A
|
A
|
||||||
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint Ԣס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2~
|
||||||
|
|
|
|
||||||
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2{
|
zD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\additional_project_files.txt Ԣס<EFBFBD>2 <20><><EFBFBD><EFBFBD><EFBFBD>2{
|
||||||
y
|
y
|
||||||
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build.json Ԣס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>
|
||||||
~
|
~
|
||||||
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2m
|
|D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\android_gradle_build_mini.json Ԣס<EFBFBD>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2m
|
||||||
k
|
k
|
||||||
iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2q
|
iD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja Ԣס<EFBFBD>2<18><> <20><><EFBFBD><EFBFBD><EFBFBD>2q
|
||||||
o
|
o
|
||||||
mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2v
|
mD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build.ninja.txt Ԣס<EFBFBD>2v
|
||||||
t
|
t
|
||||||
rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
rD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\build_file_index.txt Ԣס<EFBFBD>2
|
||||||
K <20><><EFBFBD><EFBFBD><EFBFBD>2w
|
K <20><><EFBFBD><EFBFBD><EFBFBD>2w
|
||||||
u
|
u
|
||||||
sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json Ԣס<D4A2>2 {
|
sD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json Ԣס<D4A2>2 {
|
||||||
y
|
y
|
||||||
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin Ԣס<D4A2>2
|
wD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\compile_commands.json.bin Ԣס<D4A2>2
|
||||||
<EFBFBD>
|
<EFBFBD>
|
||||||
|
|
||||||
}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt Ԣס<D4A2>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
}D:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\metadata_generation_command.txt Ԣס<D4A2>2<18> <20><><EFBFBD><EFBFBD><EFBFBD>2t
|
||||||
r
|
r
|
||||||
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json Ԣס<D4A2>2
|
pD:\KULIAH\Matkul\SKRIPSI\penyaluran_app\penyaluran_app\android\app\.cxx\Debug\626b5o2n\x86_64\prefab_config.json Ԣס<D4A2>2
|
||||||
( <20><><EFBFBD><EFBFBD><EFBFBD>2y
|
( <20><><EFBFBD><EFBFBD><EFBFBD>2y
|
@ -19,6 +19,11 @@ import 'package:penyaluran_app/app/widgets/inputs/text_input.dart';
|
|||||||
class DetailPengaduanView extends GetView<PengaduanController> {
|
class DetailPengaduanView extends GetView<PengaduanController> {
|
||||||
const DetailPengaduanView({Key? key}) : super(key: key);
|
const DetailPengaduanView({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// Definisi konstanta warna status untuk konsistensi
|
||||||
|
static const Color statusMenungguColor = Colors.orange;
|
||||||
|
static const Color statusTindakanColor = Colors.blue;
|
||||||
|
static const Color statusSelesaiColor = Colors.green;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Map<String, dynamic> args = Get.arguments ?? {};
|
final Map<String, dynamic> args = Get.arguments ?? {};
|
||||||
@ -151,15 +156,15 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
|
|
||||||
switch (pengaduan.status?.toUpperCase()) {
|
switch (pengaduan.status?.toUpperCase()) {
|
||||||
case 'MENUNGGU':
|
case 'MENUNGGU':
|
||||||
statusColor = Colors.orange;
|
statusColor = statusMenungguColor;
|
||||||
statusText = 'Menunggu';
|
statusText = 'Menunggu';
|
||||||
break;
|
break;
|
||||||
case 'TINDAKAN':
|
case 'TINDAKAN':
|
||||||
statusColor = Colors.blue;
|
statusColor = statusTindakanColor;
|
||||||
statusText = 'Tindakan';
|
statusText = 'Tindakan';
|
||||||
break;
|
break;
|
||||||
case 'SELESAI':
|
case 'SELESAI':
|
||||||
statusColor = Colors.green;
|
statusColor = statusSelesaiColor;
|
||||||
statusText = 'Selesai';
|
statusText = 'Selesai';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -236,21 +241,21 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
_buildStatusGuideItem(
|
_buildStatusGuideItem(
|
||||||
'MENUNGGU',
|
'MENUNGGU',
|
||||||
'Pengaduan baru yang belum ditindaklanjuti',
|
'Pengaduan baru yang belum ditindaklanjuti',
|
||||||
Colors.orange,
|
statusMenungguColor,
|
||||||
Icons.hourglass_empty,
|
Icons.hourglass_empty,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_buildStatusGuideItem(
|
_buildStatusGuideItem(
|
||||||
'TINDAKAN',
|
'TINDAKAN',
|
||||||
'Pengaduan sedang dalam proses penanganan',
|
'Pengaduan sedang dalam proses penanganan',
|
||||||
Colors.blue,
|
statusTindakanColor,
|
||||||
Icons.engineering,
|
Icons.engineering,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
_buildStatusGuideItem(
|
_buildStatusGuideItem(
|
||||||
'SELESAI',
|
'SELESAI',
|
||||||
'Pengaduan telah selesai ditangani',
|
'Pengaduan telah selesai ditangani',
|
||||||
Colors.green,
|
statusSelesaiColor,
|
||||||
Icons.check_circle,
|
Icons.check_circle,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -283,7 +288,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
'PROSES',
|
'PROSES',
|
||||||
'Dalam Proses',
|
'Dalam Proses',
|
||||||
'Tindakan sedang dilakukan',
|
'Tindakan sedang dilakukan',
|
||||||
Colors.blue,
|
statusTindakanColor,
|
||||||
Icons.sync,
|
Icons.sync,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
@ -291,7 +296,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
'SELESAI',
|
'SELESAI',
|
||||||
'Selesai',
|
'Selesai',
|
||||||
'Tindakan telah selesai',
|
'Tindakan telah selesai',
|
||||||
Colors.green,
|
statusSelesaiColor,
|
||||||
Icons.check_circle,
|
Icons.check_circle,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -539,19 +544,24 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
case 'MENUNGGU':
|
case 'MENUNGGU':
|
||||||
return StatusPill(
|
return StatusPill(
|
||||||
status: 'Menunggu',
|
status: 'Menunggu',
|
||||||
backgroundColor: Colors.orange,
|
backgroundColor: statusMenungguColor,
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
);
|
);
|
||||||
case 'TINDAKAN':
|
case 'TINDAKAN':
|
||||||
return StatusPill(
|
return StatusPill(
|
||||||
status: 'Tindakan',
|
status: 'Tindakan',
|
||||||
backgroundColor: Colors.blue,
|
backgroundColor: statusTindakanColor,
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
);
|
);
|
||||||
case 'SELESAI':
|
case 'SELESAI':
|
||||||
return StatusPill.completed(status: 'Selesai');
|
return StatusPill(
|
||||||
|
status: 'Selesai',
|
||||||
|
backgroundColor: statusSelesaiColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return StatusPill(
|
return StatusPill(
|
||||||
status: status ?? 'Tidak Diketahui',
|
status: status ?? 'Tidak Diketahui',
|
||||||
@ -613,7 +623,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
status == 'MENUNGGU' ||
|
status == 'MENUNGGU' ||
|
||||||
status == 'TINDAKAN' ||
|
status == 'TINDAKAN' ||
|
||||||
status == 'SELESAI',
|
status == 'SELESAI',
|
||||||
Colors.orange,
|
statusMenungguColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -622,7 +632,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
'Tindakan',
|
'Tindakan',
|
||||||
status == 'TINDAKAN',
|
status == 'TINDAKAN',
|
||||||
status == 'TINDAKAN' || status == 'SELESAI',
|
status == 'TINDAKAN' || status == 'SELESAI',
|
||||||
Colors.blue,
|
statusTindakanColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -631,7 +641,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
'Selesai',
|
'Selesai',
|
||||||
status == 'SELESAI',
|
status == 'SELESAI',
|
||||||
status == 'SELESAI',
|
status == 'SELESAI',
|
||||||
Colors.green,
|
statusSelesaiColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -646,7 +656,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
icon: const Icon(Icons.engineering),
|
icon: const Icon(Icons.engineering),
|
||||||
label: const Text('Tambah Tindakan'),
|
label: const Text('Tambah Tindakan'),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.blue,
|
backgroundColor: statusTindakanColor,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
minimumSize: const Size(double.infinity, 40),
|
minimumSize: const Size(double.infinity, 40),
|
||||||
),
|
),
|
||||||
@ -662,7 +672,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: const Text('Tambah Tindakan'),
|
label: const Text('Tambah Tindakan'),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.blue,
|
backgroundColor: statusTindakanColor,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -676,7 +686,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
icon: const Icon(Icons.check_circle),
|
icon: const Icon(Icons.check_circle),
|
||||||
label: const Text('Selesaikan'),
|
label: const Text('Selesaikan'),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.green,
|
backgroundColor: statusSelesaiColor,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -687,15 +697,15 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.green.shade50,
|
color: statusSelesaiColor.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
border: Border.all(color: Colors.green.shade200),
|
border: Border.all(color: statusSelesaiColor.withOpacity(0.3)),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.check_circle,
|
Icons.check_circle,
|
||||||
color: Colors.green,
|
color: statusSelesaiColor,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@ -703,7 +713,7 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'Pengaduan telah selesai ditangani',
|
'Pengaduan telah selesai ditangani',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.green.shade800,
|
color: statusSelesaiColor,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -921,8 +931,9 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
|
|
||||||
// Informasi penyaluran
|
// Informasi penyaluran
|
||||||
_buildInfoRow('Nama Penyaluran', pengaduan.namaPenyaluran),
|
_buildInfoRow('Nama Penyaluran', pengaduan.namaPenyaluran),
|
||||||
_buildInfoRow('Jenis Bantuan', pengaduan.jenisBantuan),
|
_buildInfoRow('Stok Bantuan', pengaduan.stokBantuan!['nama']),
|
||||||
_buildInfoRow('Jumlah Bantuan', pengaduan.jumlahBantuan),
|
_buildInfoRow('Jumlah Bantuan',
|
||||||
|
'${pengaduan.jumlahBantuan} ${pengaduan.stokBantuan!['satuan']}'),
|
||||||
_buildInfoRow('Deskripsi', pengaduan.deskripsiPenyaluran),
|
_buildInfoRow('Deskripsi', pengaduan.deskripsiPenyaluran),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -1022,10 +1033,10 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
Color dotColor;
|
Color dotColor;
|
||||||
switch (tindakan.statusTindakan) {
|
switch (tindakan.statusTindakan) {
|
||||||
case 'SELESAI':
|
case 'SELESAI':
|
||||||
dotColor = Colors.green;
|
dotColor = statusSelesaiColor;
|
||||||
break;
|
break;
|
||||||
case 'PROSES':
|
case 'PROSES':
|
||||||
dotColor = Colors.blue;
|
dotColor = statusTindakanColor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dotColor = Colors.grey;
|
dotColor = Colors.grey;
|
||||||
@ -1989,8 +2000,8 @@ class DetailPengaduanView extends GetView<PengaduanController> {
|
|||||||
: (newStatus == 'TINDAKAN' ? 'Tindakan' : 'Selesai');
|
: (newStatus == 'TINDAKAN' ? 'Tindakan' : 'Selesai');
|
||||||
|
|
||||||
Color statusColor = newStatus == 'MENUNGGU'
|
Color statusColor = newStatus == 'MENUNGGU'
|
||||||
? Colors.orange
|
? statusMenungguColor
|
||||||
: (newStatus == 'TINDAKAN' ? Colors.blue : Colors.green);
|
: (newStatus == 'TINDAKAN' ? statusTindakanColor : statusSelesaiColor);
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -9,30 +9,62 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return RefreshIndicator(
|
||||||
child: Padding(
|
onRefresh: controller.refreshData,
|
||||||
padding: const EdgeInsets.all(16.0),
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.all(16.0),
|
||||||
// Ringkasan pengaduan
|
child: Column(
|
||||||
_buildPengaduanSummary(context),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Ringkasan pengaduan
|
||||||
|
_buildPengaduanSummary(context),
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
// Filter dan pencarian
|
// Filter dan pencarian
|
||||||
_buildFilterSearch(context),
|
_buildFilterSearch(context),
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
// Informasi terakhir update
|
||||||
|
_buildLastUpdateInfo(context),
|
||||||
|
|
||||||
// Daftar pengaduan
|
const SizedBox(height: 20),
|
||||||
_buildPengaduanList(context),
|
|
||||||
],
|
// Daftar pengaduan
|
||||||
|
_buildPengaduanList(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tambahkan widget untuk menampilkan waktu terakhir update
|
||||||
|
Widget _buildLastUpdateInfo(BuildContext context) {
|
||||||
|
final lastUpdate = DateTime
|
||||||
|
.now(); // Gunakan waktu saat ini atau dari controller jika tersedia
|
||||||
|
final formattedDate = DateTimeHelper.formatDateTimeWithHour(lastUpdate);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.update, size: 16, color: Colors.grey[600]),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'Data terupdate: $formattedDate',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildPengaduanSummary(BuildContext context) {
|
Widget _buildPengaduanSummary(BuildContext context) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
return Container(
|
return Container(
|
||||||
@ -160,75 +192,36 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
color: Colors.grey.shade100,
|
color: Colors.grey.shade100,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: PopupMenuButton<int>(
|
||||||
onPressed: () {
|
|
||||||
// Tampilkan dialog filter
|
|
||||||
_showFilterDialog(context);
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.filter_list),
|
icon: const Icon(Icons.filter_list),
|
||||||
tooltip: 'Filter',
|
tooltip: 'Filter',
|
||||||
|
onSelected: (index) {
|
||||||
|
controller.changeCategory(index);
|
||||||
|
},
|
||||||
|
itemBuilder: (context) => [
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 0,
|
||||||
|
child: Text('Semua'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 1,
|
||||||
|
child: Text('Diproses'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 2,
|
||||||
|
child: Text('Tindakan'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 3,
|
||||||
|
child: Text('Selesai'),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showFilterDialog(BuildContext context) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => AlertDialog(
|
|
||||||
title: const Text('Filter Pengaduan'),
|
|
||||||
content: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Obx(() => RadioListTile<int>(
|
|
||||||
title: const Text('Semua'),
|
|
||||||
value: 0,
|
|
||||||
groupValue: controller.selectedCategoryIndex.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.changeCategory(value!);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
Obx(() => RadioListTile<int>(
|
|
||||||
title: const Text('Diproses'),
|
|
||||||
value: 1,
|
|
||||||
groupValue: controller.selectedCategoryIndex.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.changeCategory(value!);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
Obx(() => RadioListTile<int>(
|
|
||||||
title: const Text('Tindakan'),
|
|
||||||
value: 2,
|
|
||||||
groupValue: controller.selectedCategoryIndex.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.changeCategory(value!);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
Obx(() => RadioListTile<int>(
|
|
||||||
title: const Text('Selesai'),
|
|
||||||
value: 3,
|
|
||||||
groupValue: controller.selectedCategoryIndex.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.changeCategory(value!);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: const Text('Batal'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildPengaduanList(BuildContext context) {
|
Widget _buildPengaduanList(BuildContext context) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
if (controller.isLoading.value) {
|
if (controller.isLoading.value) {
|
||||||
@ -248,16 +241,16 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.inbox_outlined,
|
Icons.inbox_outlined,
|
||||||
size: 80,
|
size: 80,
|
||||||
color: Colors.grey,
|
color: Colors.grey.shade400,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'Belum ada pengaduan',
|
'Belum ada pengaduan',
|
||||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
color: Colors.grey,
|
color: Colors.grey.shade600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -278,10 +271,11 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
Text(
|
||||||
icon: const Icon(Icons.refresh),
|
'${DateTimeHelper.formatNumber(filteredPengaduan.length)} item',
|
||||||
onPressed: () => controller.refreshData(),
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
tooltip: 'Refresh',
|
color: Colors.grey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -344,6 +338,7 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -352,9 +347,10 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis,
|
// overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
Container(
|
Container(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
@ -383,63 +379,6 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
'NIK: ${item.warga?['nik'] ?? ''}',
|
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
if (item.penerimaPenyaluran != null) ...[
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey.shade100,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'Penyaluran: ${item.namaPenyaluran}',
|
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.blue.shade50,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'Jenis: ${item.jenisBantuan}',
|
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.green.shade50,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'Jumlah: ${item.jumlahBantuan}',
|
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
item.deskripsi ?? '',
|
item.deskripsi ?? '',
|
||||||
@ -447,24 +386,72 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 12),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Expanded(
|
||||||
Icons.calendar_today,
|
child: _buildItemDetail(
|
||||||
size: 14,
|
context,
|
||||||
color: Colors.grey,
|
icon: Icons.person,
|
||||||
|
label: 'Pelapor',
|
||||||
|
value: item.warga?['nama_lengkap'] ?? '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
Expanded(
|
||||||
Text(
|
child: _buildItemDetail(
|
||||||
formattedDate,
|
context,
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
icon: Icons.numbers,
|
||||||
color: Colors.grey,
|
label: 'NIK',
|
||||||
),
|
value: item.warga?['nik'] ?? '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
if (item.penerimaPenyaluran != null) ...[
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.shopping_bag,
|
||||||
|
label: 'Jumlah',
|
||||||
|
value:
|
||||||
|
'${item.jumlahBantuan} ${item.stokBantuan['satuan']}',
|
||||||
|
)),
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.inventory,
|
||||||
|
label: 'Stok Bantuan',
|
||||||
|
value: item.stokBantuan['nama'] ?? '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.category,
|
||||||
|
label: 'Nama Penyaluran',
|
||||||
|
value: item.namaPenyaluran ?? '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.calendar_today,
|
||||||
|
label: 'Tanggal',
|
||||||
|
value: formattedDate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 12),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: _buildActionButtons(context, item),
|
children: _buildActionButtons(context, item),
|
||||||
@ -475,6 +462,42 @@ class PengaduanView extends GetView<PengaduanController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildItemDetail(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
}) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
List<Widget> _buildActionButtons(BuildContext context, dynamic item) {
|
List<Widget> _buildActionButtons(BuildContext context, dynamic item) {
|
||||||
final status = item.status?.toUpperCase();
|
final status = item.status?.toUpperCase();
|
||||||
|
|
||||||
|
657
lib/app/modules/petugas_desa/views/pengaduan_view_backup.dart
Normal file
657
lib/app/modules/petugas_desa/views/pengaduan_view_backup.dart
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pengaduan_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||||
|
import 'package:penyaluran_app/app/utils/date_time_helper.dart';
|
||||||
|
|
||||||
|
class PengaduanView extends GetView<PengaduanController> {
|
||||||
|
const PengaduanView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Ringkasan pengaduan
|
||||||
|
_buildPengaduanSummary(context),
|
||||||
|
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// Filter dan pencarian
|
||||||
|
_buildFilterSearch(context),
|
||||||
|
|
||||||
|
// Informasi terakhir update
|
||||||
|
_buildLastUpdateInfo(context),
|
||||||
|
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
|
// Daftar pengaduan
|
||||||
|
_buildPengaduanList(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan widget untuk menampilkan waktu terakhir update
|
||||||
|
Widget _buildLastUpdateInfo(BuildContext context) {
|
||||||
|
return Obx(() {
|
||||||
|
final lastUpdate = DateTime
|
||||||
|
.now(); // Gunakan waktu saat ini atau dari controller jika tersedia
|
||||||
|
final formattedDate = DateTimeHelper.formatDateTimeWithHour(lastUpdate);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.update, size: 16, color: Colors.grey[600]),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'Data terupdate: $formattedDate',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPengaduanSummary(BuildContext context) {
|
||||||
|
return Obx(() {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: AppTheme.primaryGradient,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Ringkasan Pengaduan',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildSummaryItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.pending_actions,
|
||||||
|
title: 'Diproses',
|
||||||
|
value: controller.jumlahDiproses.toString(),
|
||||||
|
color: Colors.orange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildSummaryItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.engineering,
|
||||||
|
title: 'Tindakan',
|
||||||
|
value: controller.jumlahTindakan.toString(),
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildSummaryItem(
|
||||||
|
context,
|
||||||
|
icon: Icons.check_circle,
|
||||||
|
title: 'Selesai',
|
||||||
|
value: controller.jumlahSelesai.toString(),
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSummaryItem(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String title,
|
||||||
|
required String value,
|
||||||
|
required Color color,
|
||||||
|
}) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
icon,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildFilterSearch(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
controller: controller.searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Cari pengaduan...',
|
||||||
|
prefixIcon: const Icon(Icons.search),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.grey.shade100,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 0),
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
// Implementasi pencarian
|
||||||
|
controller.refreshData();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey.shade100,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: PopupMenuButton<int>(
|
||||||
|
icon: const Icon(Icons.filter_list),
|
||||||
|
tooltip: 'Filter',
|
||||||
|
onSelected: (index) {
|
||||||
|
controller.changeCategory(index);
|
||||||
|
},
|
||||||
|
itemBuilder: (context) => [
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 0,
|
||||||
|
child: Text('Semua'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 1,
|
||||||
|
child: Text('Diproses'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 2,
|
||||||
|
child: Text('Tindakan'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 3,
|
||||||
|
child: Text('Selesai'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPengaduanList(BuildContext context) {
|
||||||
|
return Obx(() {
|
||||||
|
if (controller.isLoading.value) {
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(20.0),
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final filteredPengaduan = controller.getFilteredPengaduan();
|
||||||
|
|
||||||
|
if (filteredPengaduan.isEmpty) {
|
||||||
|
return Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.inbox_outlined,
|
||||||
|
size: 80,
|
||||||
|
color: Colors.grey.shade400,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Belum ada pengaduan',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
color: Colors.grey.shade600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Daftar Pengaduan',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${DateTimeHelper.formatNumber(filteredPengaduan.length)} item',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.refresh),
|
||||||
|
onPressed: () => controller.refreshData(),
|
||||||
|
tooltip: 'Refresh',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
...filteredPengaduan
|
||||||
|
.map((item) => _buildPengaduanItem(context, item)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPengaduanItem(BuildContext context, dynamic item) {
|
||||||
|
Color statusColor;
|
||||||
|
IconData statusIcon;
|
||||||
|
|
||||||
|
switch (item.status?.toUpperCase()) {
|
||||||
|
case 'MENUNGGU':
|
||||||
|
statusColor = AppTheme.warningColor;
|
||||||
|
statusIcon = Icons.pending;
|
||||||
|
break;
|
||||||
|
case 'TINDAKAN':
|
||||||
|
statusColor = AppTheme.infoColor;
|
||||||
|
statusIcon = Icons.sync;
|
||||||
|
break;
|
||||||
|
case 'SELESAI':
|
||||||
|
statusColor = AppTheme.successColor;
|
||||||
|
statusIcon = Icons.check_circle;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusColor = Colors.grey;
|
||||||
|
statusIcon = Icons.help_outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format tanggal menggunakan DateTimeHelper
|
||||||
|
String formattedDate = '';
|
||||||
|
if (item.tanggalPengaduan != null) {
|
||||||
|
formattedDate = DateTimeHelper.formatDate(item.tanggalPengaduan);
|
||||||
|
} else if (item.createdAt != null) {
|
||||||
|
formattedDate = DateTimeHelper.formatDate(item.createdAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.grey.withAlpha(26),
|
||||||
|
spreadRadius: 1,
|
||||||
|
blurRadius: 3,
|
||||||
|
offset: const Offset(0, 1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
item.warga?['nama'] ?? item.judul ?? '',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: statusColor.withOpacity(0.1),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
statusIcon,
|
||||||
|
size: 16,
|
||||||
|
color: statusColor,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
item.status ?? '',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: statusColor,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
_buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.person,
|
||||||
|
label: 'NIK',
|
||||||
|
value: item.warga?['nik'] ?? '',
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
if (item.penerimaPenyaluran != null) ...[
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.category,
|
||||||
|
label: 'Penyaluran',
|
||||||
|
value: item.namaPenyaluran ?? '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.inventory,
|
||||||
|
label: 'Jenis',
|
||||||
|
value: item.jenisBantuan ?? '',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.shopping_bag,
|
||||||
|
label: 'Jumlah',
|
||||||
|
value: item.jumlahBantuan ?? '',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
item.deskripsi ?? '',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildItemDetail(
|
||||||
|
context,
|
||||||
|
icon: Icons.calendar_today,
|
||||||
|
label: 'Tanggal',
|
||||||
|
value: formattedDate,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: _buildActionButtons(context, item),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildItemDetail(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
}) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildActionButtons(BuildContext context, dynamic item) {
|
||||||
|
final status = item.status?.toUpperCase();
|
||||||
|
|
||||||
|
if (status == 'MENUNGGU') {
|
||||||
|
return [
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi untuk memproses pengaduan
|
||||||
|
_showTindakanDialog(context, item);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.engineering, size: 18),
|
||||||
|
label: const Text('Tindakan'),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.blue,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Navigasi ke halaman detail pengaduan
|
||||||
|
Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.info_outline, size: 18),
|
||||||
|
label: const Text('Detail'),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.grey,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
} else if (status == 'TINDAKAN') {
|
||||||
|
return [
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Implementasi untuk menyelesaikan pengaduan
|
||||||
|
_showSelesaikanDialog(context, item);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.check_circle, size: 18),
|
||||||
|
label: const Text('Selesaikan'),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.green,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Navigasi ke halaman detail pengaduan
|
||||||
|
Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.info_outline, size: 18),
|
||||||
|
label: const Text('Detail'),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.grey,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// Navigasi ke halaman detail pengaduan
|
||||||
|
Get.toNamed('/detail-pengaduan', arguments: {'id': item.id});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.info_outline, size: 18),
|
||||||
|
label: const Text('Detail'),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.grey,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showTindakanDialog(BuildContext context, dynamic item) {
|
||||||
|
controller.tindakanController.clear();
|
||||||
|
controller.catatanController.clear();
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Tindakan Pengaduan'),
|
||||||
|
content: Form(
|
||||||
|
key: controller.tindakanFormKey,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text('Pengaduan dari: ${item.warga?['nama'] ?? ''}'),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: controller.tindakanController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Tindakan yang dilakukan',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
maxLines: 3,
|
||||||
|
validator: controller.validateTindakan,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
TextFormField(
|
||||||
|
controller: controller.catatanController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Catatan (opsional)',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Batal'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.tindakanFormKey.currentState!.validate()) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
controller.tambahTindakanPengaduan(
|
||||||
|
pengaduanId: item.id!,
|
||||||
|
tindakan: controller.tindakanController.text,
|
||||||
|
kategoriTindakan: 'VERIFIKASI_DATA',
|
||||||
|
statusTindakan: 'PROSES',
|
||||||
|
prioritas: 'SEDANG',
|
||||||
|
catatan: controller.catatanController.text.isEmpty
|
||||||
|
? null
|
||||||
|
: controller.catatanController.text,
|
||||||
|
buktiTindakanPaths: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Simpan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showSelesaikanDialog(BuildContext context, dynamic item) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Selesaikan Pengaduan'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text('Pengaduan dari: ${item.warga?['nama'] ?? ''}'),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text(
|
||||||
|
'Apakah Anda yakin ingin menyelesaikan pengaduan ini?',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Batal'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
controller.selesaikanPengaduan(item.id!);
|
||||||
|
},
|
||||||
|
child: const Text('Selesaikan'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user