diff --git a/src/components/DashboardGrafik.tsx b/src/components/DashboardGrafik.tsx index ef31883..0748231 100644 --- a/src/components/DashboardGrafik.tsx +++ b/src/components/DashboardGrafik.tsx @@ -1,6 +1,6 @@ import apiFetch from "@/lib/apiFetch"; -import { Card, Divider, Flex, Stack, Title } from "@mantine/core"; -import { IconSettings } from "@tabler/icons-react"; +import { Card, Divider, Flex, Stack, Text, Title } from "@mantine/core"; +import { IconChartBar } from "@tabler/icons-react"; import type { EChartsOption } from "echarts"; import EChartsReact from "echarts-for-react"; import { useEffect, useState } from "react"; @@ -21,7 +21,7 @@ export default function DashboardGrafik() { darkMode: true, animation: true, legend: { - textStyle: { color: "#fff" } // warna legend putih + textStyle: { color: "#fff" } }, tooltip: {}, dataset: { @@ -34,7 +34,8 @@ export default function DashboardGrafik() { }, yAxis: { type: "value", - minInterval: 1 + minInterval: 1, + axisLabel: { color: "#fff" } }, color: ["#1abc9c", "#10816aff"], series: [ @@ -62,20 +63,19 @@ export default function DashboardGrafik() { boxShadow: "0 0 25px rgba(0,255,200,0.08)", }} > - + - - System Performance - - + + + Grafik Pengaduan dan Pelayanan Surat + + 7 Hari Terakhir + + - - {/* - - - */} + diff --git a/src/components/DashboardLastData.tsx b/src/components/DashboardLastData.tsx index c881b77..47bcac3 100644 --- a/src/components/DashboardLastData.tsx +++ b/src/components/DashboardLastData.tsx @@ -80,7 +80,7 @@ export default function DashboardLastData() { (""); const [loading, setLoading] = useState(false); const [typeFile, setTypeFile] = useState(""); + const [error, setError] = useState(false); useEffect(() => { if (open && fileName) { @@ -27,23 +28,36 @@ export default function ModalFile({ open, onClose, folder, fileName }: { open: b // load file const urlApi = '/api/pengaduan/image?folder=' + folder + '&fileName=' + fileName; const res = await fetch(urlApi); - if (!res.ok) + if (!res.ok) { + setError(true); return notification({ title: "Error", message: "Failed to load image", type: "error", }); + } const blob = await res.blob(); const url = URL.createObjectURL(blob); setViewFile(url); } catch (err) { - console.error("Gagal load gambar:", err); + setError(true); + notification({ + title: "Error", + message: "Failed to load image", + type: "error", + }); } finally { setLoading(false); } }; + useEffect(() => { + if (error) { + onClose(); + } + }, [error]); + return ( diff --git a/src/lib/categoryPelayananSurat.ts b/src/lib/categoryPelayananSurat.ts index 0db02cb..c03ee14 100644 --- a/src/lib/categoryPelayananSurat.ts +++ b/src/lib/categoryPelayananSurat.ts @@ -17,7 +17,7 @@ export const categoryPelayananSurat = [ { name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" }, { name: "akta cerai", desc: "Fotokopi Akta Cerai bagi yang berstatus janda/duda" } ], - dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "status perkawinan"] + dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "agama", "pekerjaan"] }, { id: "skdomisiliorganisasi", @@ -27,7 +27,7 @@ export const categoryPelayananSurat = [ { name: "skt organisasi", desc: "Fotokopi Surat Keterangan Terdaftar (SKT) Organisasi atau Pengukuhan Kelompok" }, { name: "susunan pengurus", desc: "Jika Pengajuan baru pembuatan SKT maka melengkapi Susunan Pengurus lengkap denganKop Organisasi" } ], - dataText: ["nama organisasi", "alamat organisasi", "nama pemohon", "jabatan pemohon", "kontak", "penanggung jawab", "tanggal berdiri"] + dataText: ["nama organisasi", "jenis organisasi", "alamat organisasi/sekretariat", "no telepon", "nama pimpinan", "keperluan"] }, { id: "skkelahiran", @@ -45,7 +45,7 @@ export const categoryPelayananSurat = [ { name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" }, { name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" } ], - dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "polsek"] + dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "agama", "alamat", "pekerjaan", "polsek"] }, { id: "skkematian", @@ -55,7 +55,7 @@ export const categoryPelayananSurat = [ { name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" }, { name: "surat kematian", desc: "Surat Keterangan Kematian dari Rumah Sakit/Dokter (jika ada)" } ], - dataText: ["nama almarhum", "nik", "tempat tanggal lahir", "alamat", "tanggal kematian", "waktu kematian", "penyebab kematian"] + dataText: ["nik pelapor", "nama pelapor", "pekerjaan pelapor", "alamat pelapor", "hubungan pelapor dengan almarhum", "nama almarhum", "nik almarhum", "tempat tanggal lahir almarhum", "alamat almarhum", "agama almarhum", "tanggal kematian", "waktu kematian", "tempat kematian", "penyebab kematian"] }, { id: "skpenghasilan", @@ -65,7 +65,7 @@ export const categoryPelayananSurat = [ { name: "ktp ortu/kk", desc: "Fotokopi KTP orang tua atau Kartu Keluarga" }, { name: "surat pernyataan", desc: "Surat Pernyataan Penghasilan bermaterai" } ], - dataText: ["nama", "nik", "alamat", "pekerjaan", "jenis usaha", "penghasilan", "alasan permohonan"] + dataText: ["nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "pekerjaan", "penghasilan", "alasan permohonan"] }, { id: "sktempatusaha", @@ -76,7 +76,7 @@ export const categoryPelayananSurat = [ { name: "foto lokasi", desc: "Foto lokasi usaha dicetak dalam selembar kertas, diparaf dan distempel oleh Kelian" }, { name: "sppt/sertifikat/sewa", desc: "Fotokopi SPPT, Sertifikat Hak Milik, Surat Perjanjian Sewa, atau Kwitansi Pembayaran Sewa 3 bulan terakhir" } ], - dataText: ["nama usaha", "bidang usaha", "alamat usaha", "status tempat usaha", "luas tempat usaha", "jumlah karyawan", "tujuan pembuatan surat"] + dataText: ["nik", "nama pemilik", "tempat tanggal lahir", "alamat pemilik", "nama usaha", "bidang usaha", "alamat usaha", "status tempat usaha", "luas tempat usaha", "jumlah karyawan", "tujuan pembuatan surat"] }, { id: "sktidakmampu", @@ -104,6 +104,6 @@ export const categoryPelayananSurat = [ { name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" }, { name: "ktp/kia/kk", desc: "Fotokopi KTP, KIA, atau Kartu Keluarga" } ], - dataText: ["nama anak", "nama ayah", "status ayah", "nama ibu", "status ibu"] + dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "pekerjaan", "nama ayah", "status ayah", "nama ibu", "status ibu"] } ]; diff --git a/src/pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page.tsx b/src/pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page.tsx index a7cef95..c015d49 100644 --- a/src/pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page.tsx +++ b/src/pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page.tsx @@ -1,3 +1,4 @@ +import ModalFile from "@/components/ModalFile"; import ModalSurat from "@/components/ModalSurat"; import notification from "@/components/notificationGlobal"; import apiFetch from "@/lib/apiFetch"; @@ -77,7 +78,9 @@ function DetailDataPengajuan({ data, syaratDokumen, dataText, onAction }: { data const [host, setHost] = useState(null); const [noSurat, setNoSurat] = useState(""); const [openedPreview, setOpenedPreview] = useState(false); + const [openedPreviewFile, setOpenedPreviewFile] = useState(false); const [permissions, setPermissions] = useState([]); + const [viewImg, setViewImg] = useState(""); useEffect(() => { async function fetchHost() { @@ -128,8 +131,22 @@ function DetailDataPengajuan({ data, syaratDokumen, dataText, onAction }: { data } } + useShallowEffect(() => { + if (viewImg) { + setOpenedPreviewFile(true); + } + }, [viewImg]); + return ( <> + { + setOpenedPreviewFile(false) + }} + folder="syarat-dokumen" + fileName={viewImg} + /> {/* MODAL KONFIRMASI */} {syaratDokumen?.map((v: any) => ( - + { setViewImg(v.value) }}> {v.jenis} diff --git a/src/pages/scr/dashboard/pengaduan/detail_page.tsx b/src/pages/scr/dashboard/pengaduan/detail_page.tsx index e394487..dacebc4 100644 --- a/src/pages/scr/dashboard/pengaduan/detail_page.tsx +++ b/src/pages/scr/dashboard/pengaduan/detail_page.tsx @@ -1,3 +1,4 @@ +import ModalFile from "@/components/ModalFile"; import notification from "@/components/notificationGlobal"; import apiFetch from "@/lib/apiFetch"; import { @@ -10,13 +11,12 @@ import { Flex, Grid, Group, - Image, Modal, Stack, Table, Text, Textarea, - Title, + Title } from "@mantine/core"; import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import { @@ -73,9 +73,7 @@ export default function DetailPengaduanPage() { function DetailDataPengaduan({ data, onAction }: { data: any, onAction: () => void }) { const [opened, { open, close }] = useDisclosure(false); const [catModal, setCatModal] = useState<"tolak" | "terima">("tolak"); - const [imageSrc, setImageSrc] = useState(null); - const [openedModalImage, { open: openModalImage, close: closeModalImage }] = - useDisclosure(false); + const [openedPreview, setOpenedPreview] = useState(false); const [keterangan, setKeterangan] = useState(""); const [host, setHost] = useState(null); const [permissions, setPermissions] = useState([]); @@ -173,14 +171,12 @@ function DetailDataPengaduan({ data, onAction }: { data: any, onAction: () => vo {/* MODAL GAMBAR */} - - - + setOpenedPreview(false)} + folder="pengaduan" + fileName={data?.image} + /> vo { data?.image != null && data?.image != "" ? - { }}> + { setOpenedPreview(true) }}> Lihat Gambar : diff --git a/src/server/routes/dashboard_route.ts b/src/server/routes/dashboard_route.ts index d568b6f..bcdd775 100644 --- a/src/server/routes/dashboard_route.ts +++ b/src/server/routes/dashboard_route.ts @@ -57,7 +57,7 @@ const DashboardRoute = new Elysia({ const kenaikanPengaduan = dataPengaduanYesterday === 0 ? dataPengaduanToday > 0 - ? 100 + ? dataPengaduanToday * 100 : 0 : ((dataPengaduanToday - dataPengaduanYesterday) / dataPengaduanYesterday) * 100; @@ -87,7 +87,7 @@ const DashboardRoute = new Elysia({ const kenaikanPelayanan = dataPelayananYesterday === 0 ? dataPelayananToday > 0 - ? 100 + ? dataPelayananToday * 100 : 0 : ((dataPelayananToday - dataPelayananYesterday) / dataPelayananYesterday) * 100; @@ -143,6 +143,7 @@ const DashboardRoute = new Elysia({ select: { id: true, status: true, + noPengajuan: true, updatedAt: true, CategoryPelayanan: { select: { @@ -155,6 +156,7 @@ const DashboardRoute = new Elysia({ const dataPelayananFix = dataPelayanan.map((item) => { return { id: item.id, + noPengajuan: item.noPengajuan, title: item.CategoryPelayanan.name, status: item.status, updatedAt: 'terakhir diperbarui ' + getLastUpdated(item.updatedAt), diff --git a/src/server/routes/pelayanan_surat_route.ts b/src/server/routes/pelayanan_surat_route.ts index 50afd21..c1c55a8 100644 --- a/src/server/routes/pelayanan_surat_route.ts +++ b/src/server/routes/pelayanan_surat_route.ts @@ -436,13 +436,13 @@ const PelayananRoute = new Elysia({ jenis: t.String({ minLength: 1, description: "Jenis field yang dibutuhkan oleh kategori pelayanan. Biasanya dinamis.", - examples: ["nama", "alamat", "pekerjaan", "keperluan"], + examples: ["nama", "jenis kelamin", "tempat tanggal lahir", "negara", "agama", "status perkawinan", "alamat", "pekerjaan", "jenis usaha", "alamat usaha"], error: "jenis harus diisi" }), value: t.String({ minLength: 1, description: "Isi atau nilai dari jenis field terkait.", - examples: ["Budi Santoso", "Jl. Mawar No. 10", "Karyawan Swasta"], + examples: ["Budi Santoso", "Laki-laki", "Denpasar, 28 Februari 1990", "Indonesia", "Islam", "Belum menikah", "Jl. Mawar No. 10", "Karyawan Swasta", "usaha makanan", "Jl. Melati No. 21"], error: "value harus diisi" }), }), @@ -450,6 +450,14 @@ const PelayananRoute = new Elysia({ description: "Kumpulan data text dinamis sesuai kategori layanan.", examples: [ [ + { jenis: "nama", value: "Budi Santoso" }, + { jenis: "jenis kelamin", value: "Laki-laki" }, + { jenis: "tempat tanggal lahir", value: "Denpasar, 28 Februari 1990" }, + { jenis: "negara", value: "Indonesia" }, + { jenis: "agama", value: "Islam" }, + { jenis: "status perkawinan", value: "Belum menikah" }, + { jenis: "alamat", value: "Jl. Mawar No. 10" }, + { jenis: "pekerjaan", value: "Karyawan Swasta" }, { jenis: "jenis usaha", value: "usaha makanan" }, { jenis: "alamat usaha", value: "Jl. Melati No. 21" }, ]