From 03715b7c9872a1f779995d918006818823bfcda5 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 20 Nov 2025 11:57:55 +0800 Subject: [PATCH 1/4] upd: dashboard admin Deskripsi: - sk tidak mampu - sk tempat usaha - sk kematian - sk domisili organisasi - sk belum kawin - sk beda biodata diri No Issues --- src/components/ModalSurat.tsx | 18 ++- src/components/surat/SKBedaBiodataDiri.tsx | 129 ++++++++++++++++++ src/components/surat/SKBelumKawin.tsx | 79 +++++++++++ src/components/surat/SKDomisiliOrganisasi.tsx | 93 +++++++++++++ src/components/surat/SKKematian.tsx | 89 ++++++++++++ src/components/surat/SKTempatUsaha.tsx | 90 ++++++++++++ src/components/surat/SKTidakMampu.tsx | 6 +- 7 files changed, 499 insertions(+), 5 deletions(-) create mode 100644 src/components/surat/SKBedaBiodataDiri.tsx create mode 100644 src/components/surat/SKBelumKawin.tsx create mode 100644 src/components/surat/SKDomisiliOrganisasi.tsx create mode 100644 src/components/surat/SKKematian.tsx create mode 100644 src/components/surat/SKTempatUsaha.tsx diff --git a/src/components/ModalSurat.tsx b/src/components/ModalSurat.tsx index 33fb181..1ca5374 100644 --- a/src/components/ModalSurat.tsx +++ b/src/components/ModalSurat.tsx @@ -6,9 +6,14 @@ import html2canvas from "html2canvas"; import jsPDF from "jspdf"; import { useRef } from "react"; import useSWR from "swr"; +import SKBedaBiodataDiri from "./surat/SKBedaBiodataDiri"; +import SKBelumKawin from "./surat/SKBelumKawin"; +import SKDomisiliOrganisasi from "./surat/SKDomisiliOrganisasi"; import SKKelahiran from "./surat/SKKelahiran"; import SKKelakuanBaik from "./surat/SKKelakuanBaik"; +import SKKematian from "./surat/SKKematian"; import SKPenghasilan from "./surat/SKPenghasilan"; +import SKTempatUsaha from "./surat/SKTempatUsaha"; import SKTidakMampu from "./surat/SKTidakMampu"; import SKUsaha from "./surat/SKUsaha"; import SKYatim from "./surat/SKYatimPiatu"; @@ -115,8 +120,17 @@ export default function ModalSurat({ open, onClose, surat }: { open: boolean, on ? : data.data.surat.idCategory == "skyatimpiatu" ? - : <> - + : data.data.surat.idCategory == "skdomisiliorganisasi" + ? + : data.data.surat.idCategory == "skbedabiodata" + ? + : data.data.surat.idCategory == "sktempatusaha" + ? + : data.data.surat.idCategory == "skbelumkawin" + ? + : data.data.surat.idCategory == "skkematian" + ? + : <> : <> } diff --git a/src/components/surat/SKBedaBiodataDiri.tsx b/src/components/surat/SKBedaBiodataDiri.tsx new file mode 100644 index 0000000..2c0278d --- /dev/null +++ b/src/components/surat/SKBedaBiodataDiri.tsx @@ -0,0 +1,129 @@ +import _ from "lodash"; + +export default function SKBedaBiodataDiri({ data }: { data: any }) { + const getValue = (jenis: string) => + _.upperFirst( + data.surat.dataText.find((item: any) => item.jenis === jenis)?.value || "" + ); + + return ( +
+ {/* HEADER */} +
+ PEMERINTAH KABUPATEN {_.upperCase(data.setting.desaKabupaten)}
+ KECAMATAN {_.upperCase(data.setting.desaKecamatan)}
+ DESA / KELURAHAN {_.upperCase(data.setting.desaNama)}
+ Alamat: {data.setting.desaAlamat}
+ Kode Pos: {data.setting.desaPos} +
+ + {/* JUDUL */} +
+ SURAT KETERANGAN BEDA BIODATA DIRI
+ Nomor: {data.surat.noSurat} +
+ + {/* YANG BERTANDA TANGAN */} +
+ Yang bertanda tangan di bawah ini: + + + + + + + + + + + + + + + + + + + + + + + +
Nama:{data.setting.perbekelNama}
Jabatan:{data.setting.perbekelJabatan + " " + data.setting.desaNama}
Kecamatan:{data.setting.desaKecamatan}
Kabupaten:{data.setting.desaKabupaten}
+
+ + {/* IDENTITAS ORANG YG MEMINTA SURAT */} +
+ Dengan ini menerangkan bahwa berdasarkan keterangan dari yang bersangkutan: + + + + + + + + + +
Nama:{getValue("nama")}
Tempat/Tanggal Lahir:{getValue("tempat tanggal lahir")}
Jenis Kelamin:{getValue("jenis kelamin")}
Alamat:{getValue("alamat")}
Pekerjaan:{getValue("pekerjaan")}
NIK:{getValue("nik")}
+
+ +
+ Bahwa orang tersebut di atas benar merupakan orang yang sama, meskipun terdapat perbedaan data pribadi (biodata) pada beberapa dokumen, sebagai berikut: +
+ +
+ + + + + + +
1. Nama:{getValue("nama")}
Tertulis pada dokumen A:{getValue("tertulis pada dokumen a")}
Tertulis pada dokumen B:{getValue("tertulis pada dokumen b")}
+
+ +
+ + + + + + +
2. Tempat/Tanggal Lahir:{getValue("tempat tanggal lahir")}
Tertulis pada dokumen A:{getValue("tertulis pada dokumen a")}
Tertulis pada dokumen B:{getValue("tertulis pada dokumen b")}
+
+ +
+ + + + + + +
3. Nama Orang Tua:{getValue("nama orang tua")}
Tertulis pada dokumen A:{getValue("tertulis pada dokumen a")}
Tertulis pada dokumen B:{getValue("tertulis pada dokumen b")}
+
+ +
+ Perbedaan tersebut terjadi karena kesalahan penulisan/pencatatan administratif, namun yang bersangkutan adalah orang yang sama. +
+ Dengan surat keterangan ini dibuat dengan sebenar-benarnya untuk dipergunakan sebagaimana mestinya. +
+ +
+ Dikeluarkan di {data.setting.desaNama}
+ Pada tanggal {data.surat.createdAt} +
+ + {/* TANDA TANGAN */} +
+
+ +

+ Kepala Desa / Lurah {data.setting.desaNama} +



+ {data.setting.perbekelNama}
+ NIP. {data.setting.perbekelNIP} +
+
+ +
+ ); +} diff --git a/src/components/surat/SKBelumKawin.tsx b/src/components/surat/SKBelumKawin.tsx new file mode 100644 index 0000000..add1172 --- /dev/null +++ b/src/components/surat/SKBelumKawin.tsx @@ -0,0 +1,79 @@ +import _ from "lodash"; + +export default function SKBelumKawin({ data }: { data: any }) { + const getValue = (jenis: string) => + _.upperFirst( + data.surat.dataText.find((item: any) => item.jenis === jenis)?.value || "" + ); + + return ( +
+ {/* HEADER */} +
+ PEMERINTAH KABUPATEN {_.upperCase(data.setting.desaKabupaten)}
+ KECAMATAN {_.upperCase(data.setting.desaKecamatan)}
+ DESA / KELURAHAN {_.upperCase(data.setting.desaNama)}
+ Alamat: {data.setting.desaAlamat}
+ Kode Pos: {data.setting.desaPos} +
+ + {/* JUDUL */} +
+ SURAT KETERANGAN BELUM KAWIN
+ Nomor: {data.surat.noSurat} +
+ + {/* YANG BERTANDA TANGAN */} +
+ Yang bertanda tangan di bawah ini {data.setting.perbekelJabatan} {data.setting.desaNama}, Kecamatan {data.setting.desaKecamatan}, Kabupaten {data.setting.desaKabupaten}, dengan ini menerangkan bahwa: +
+ + {/* IDENTITAS ORANG YG MEMINTA SURAT */} +
+ + + + + + + + + + +
Nama:{getValue("nama")}
NIK:{getValue("nik")}
Tempat/Tanggal Lahir:{getValue("tempat tanggal lahir")}
Jenis Kelamin:{getValue("jenis kelamin")}
Agama:{getValue("agama")}
Pekerjaan:{getValue("pekerjaan")}
Alamat:{getValue("alamat")}
+
+ +
+ Berdasarkan keterangan dari yang bersangkutan dan data administrasi kependudukan yang ada di Desa {data.setting.desaNama}, + yang bersangkutan benar sampai saat ini belum pernah menikah, baik secara adat, agama, maupun hukum negara. +
+ +
+ Demikian surat keterangan ini dibuat dengan sebenarnya agar dapat digunakan sebagaimana mestinya. +
+ +
+ Dikeluarkan di {data.setting.desaNama}
+ Pada tanggal {data.surat.createdAt} +
+ + {/* TANDA TANGAN */} +
+
+

+ Pemohon +



+ {getValue("nama")}
+
+
+

+ Kepala Desa / Lurah {data.setting.desaNama} +



+ {data.setting.perbekelNama}
+ NIP. {data.setting.perbekelNIP} +
+
+ +
+ ); +} diff --git a/src/components/surat/SKDomisiliOrganisasi.tsx b/src/components/surat/SKDomisiliOrganisasi.tsx new file mode 100644 index 0000000..e4994ea --- /dev/null +++ b/src/components/surat/SKDomisiliOrganisasi.tsx @@ -0,0 +1,93 @@ +import _ from "lodash"; + +export default function SKDomisiliOrganisasi({ data }: { data: any }) { + const getValue = (jenis: string) => + _.upperFirst( + data.surat.dataText.find((item: any) => item.jenis === jenis)?.value || "" + ); + + return ( +
+ {/* HEADER */} +
+ PEMERINTAH KABUPATEN {_.upperCase(data.setting.desaKabupaten)}
+ KECAMATAN {_.upperCase(data.setting.desaKecamatan)}
+ DESA / KELURAHAN {_.upperCase(data.setting.desaNama)}
+ Alamat: {data.setting.desaAlamat}
+ Kode Pos: {data.setting.desaPos} +
+ + {/* JUDUL */} +
+ SURAT KETERANGAN DOMISILI ORGANISASI
+ Nomor: {data.surat.noSurat} +
+ + {/* YANG BERTANDA TANGAN */} +
+ Yang bertanda tangan di bawah ini: + + + + + + + + + + + + + + + + + + +
Nama:{data.setting.perbekelNama}
Jabatan:{data.setting.perbekelJabatan}
Alamat Kantor:{data.setting.desaAlamat}
+
+ + {/* IDENTITAS ORANG YG MEMINTA SURAT */} +
+ Dengan ini menerangkan bahwa: + + + + + + + + +
Nama Organisasi:{getValue("nama")}
Jenis Organisasi:{getValue("jenis kelamin")}
Alamat:{getValue("tempat tanggal lahir")}
Nomor Telepon:{getValue("negara")}
Nama Pimpinan:{getValue("agama")}
+
+ +
+ Benar bahwa organisasi tersebut berdomisili di wilayah Desa / Kelurahan {data.setting.desaNama}, Kecamatan {data.setting.desaKecamatan}, Kabupaten {data.setting.desaKabupaten}. + Dan sampai saat ini masih aktif melakukan kegiatan sesuai dengan bidangnya.
+ Surat keterangan ini dibuat untuk keperluan {getValue("keperluan")}. +
+ +
+ Demikian surat keterangan ini dibuat dengan sebenarnya agar dapat digunakan sebagaimana mestinya. +
+ +
+ Dikeluarkan di {data.setting.desaNama}
+ Pada tanggal {data.surat.createdAt} +
+ + {/* TANDA TANGAN */} +
+
+ +

+ Kepala Desa / Lurah {data.setting.desaNama} +



+ {data.setting.perbekelNama}
+ NIP. {data.setting.perbekelNIP} +
+
+ +
+ ); +} diff --git a/src/components/surat/SKKematian.tsx b/src/components/surat/SKKematian.tsx new file mode 100644 index 0000000..eb5e37c --- /dev/null +++ b/src/components/surat/SKKematian.tsx @@ -0,0 +1,89 @@ +import _ from "lodash"; + +export default function SKKematian({ data }: { data: any }) { + const getValue = (jenis: string) => + _.upperFirst( + data.surat.dataText.find((item: any) => item.jenis === jenis)?.value || "" + ); + + return ( +
+ {/* HEADER */} +
+ PEMERINTAH KABUPATEN {_.upperCase(data.setting.desaKabupaten)}
+ KECAMATAN {_.upperCase(data.setting.desaKecamatan)}
+ DESA / KELURAHAN {_.upperCase(data.setting.desaNama)}
+ Alamat: {data.setting.desaAlamat}
+ Kode Pos: {data.setting.desaPos} +
+ + {/* JUDUL */} +
+ SURAT KETERANGAN KEMATIAN
+ Nomor: {data.surat.noSurat} +
+ + {/* YANG BERTANDA TANGAN */} +
+ Yang bertanda tangan di bawah ini: + + + + + + + + +
Nama:{getValue("nama")}
NIK:{getValue("nik")}
Pekerjaan:{getValue("pekerjaan")}
Alamat:{getValue("alamat")}
Hubungan dengan almarhum/almarhumah:{getValue("hubungan dengan almarhum")}
+
+ +
+ Melaporkan bahwa: + + + + + + + + + +
Nama:{getValue("nama")}
NIK:{getValue("nik")}
Jenis Kelamin:{getValue("jenis kelamin")}
Tempat/Tanggal Lahir:{getValue("tempat tanggal lahir")}
Agama:{getValue("agama")}
Alamat:{getValue("alamat")}
+
+ +
+ Telah meninggal dunia pada: + + + + + + + +
Tanggal Kematian:{getValue("tanggal kematian")}
Waktu Kematian:{getValue("waktu kematian")}
Tempat Kematian:{getValue("tempat kematian")}
Penyebab Kematian:{getValue("penyebab kematian")}
+
+ +
+ Demikian surat keterangan ini dibuat dengan sebenarnya agar dapat digunakan sebagaimana mestinya. +
+ + {/* TANDA TANGAN */} +
+
+

+ Pemohon +



+ {getValue("nama")}
+
+
+

+ Kepala Desa / Lurah {data.setting.desaNama} +



+ {data.setting.perbekelNama}
+ NIP. {data.setting.perbekelNIP} +
+
+ +
+ ); +} diff --git a/src/components/surat/SKTempatUsaha.tsx b/src/components/surat/SKTempatUsaha.tsx new file mode 100644 index 0000000..efae86f --- /dev/null +++ b/src/components/surat/SKTempatUsaha.tsx @@ -0,0 +1,90 @@ +import _ from "lodash"; + +export default function SKTempatUsaha({ data }: { data: any }) { + const getValue = (key: string) => + _.upperFirst(data.surat.dataText.find((i: any) => i.jenis === key)?.value || ""); + + return ( +
+ {/* TITLE */} +
+ SURAT KETERANGAN TEMPAT USAHA
+ Nomor: {data.surat.noSurat} +
+ + {/* ISI */} +
+
+ Yang bertanda tangan dibawah ini, saya: +
+ + {/* DATA PEJABAT */} +
+ + + +
+ +
+ +
Dengan ini menerangkan bahwa:
+ + {/* DATA WARGA */} +
+ + + + +
+ +
+ +
Benar yang bersangkutan memiliki tempat usaha dengan keterangan seperti berikut:
+ +
+ + + + + + +
+ +

+ Surat keterangan ini dibuat untuk keperluan {getValue("alasan permohonan")}. +

+ +

+ Demikian surat keterangan ini dibuat dengan sebenarnya untuk dapat dipergunakan sebagaimana mestinya. +

+ +
+ + +
+ +

+ + {/* TANDA TANGAN */} +
+
+ {data.setting.desaNama}, {data.surat.createdAt}


+ + {data.setting.perbekelNama}
+ {data.setting.perbekelJabatan + " " + data.setting.desaNama} +
+
+
+
+ ); +} + +function Row({ label, value }: { label: string, value: string }) { + return ( +
+
{label}
+
:
+
{value}
+
+ ); +} diff --git a/src/components/surat/SKTidakMampu.tsx b/src/components/surat/SKTidakMampu.tsx index 2ef68e3..e0b62ba 100644 --- a/src/components/surat/SKTidakMampu.tsx +++ b/src/components/surat/SKTidakMampu.tsx @@ -19,7 +19,7 @@ export default function SKTidakMampu({ data }: { data: any }) { {/* DATA PEJABAT */} -
+
@@ -32,7 +32,7 @@ export default function SKTidakMampu({ data }: { data: any }) {
Dengan ini menerangkan bahwa:
{/* DATA WARGA */} -
+
@@ -61,7 +61,7 @@ export default function SKTidakMampu({ data }: { data: any }) {
{data.setting.desaNama}, {data.surat.createdAt}


- {data.setting.perbekelNama}
+ {data.setting.perbekelNama}
{data.setting.perbekelJabatan + " " + data.setting.desaNama}
From d0ff67595013f8865e9b5105ac20af54f6b77d4c Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 20 Nov 2025 16:09:36 +0800 Subject: [PATCH 2/4] upd: dashboard admin Deskripsi - edit upload ttd setting desa No Issues --- src/components/DesaSetting.tsx | 83 ++++++++++++++++--- .../dashboard/setting/detail_setting_page.tsx | 8 +- src/server/lib/rename-file.ts | 12 +++ src/server/lib/seafile.ts | 2 +- src/server/routes/pengaduan_route.ts | 16 +++- 5 files changed, 96 insertions(+), 25 deletions(-) create mode 100644 src/server/lib/rename-file.ts diff --git a/src/components/DesaSetting.tsx b/src/components/DesaSetting.tsx index d136937..c7871d3 100644 --- a/src/components/DesaSetting.tsx +++ b/src/components/DesaSetting.tsx @@ -1,8 +1,10 @@ import apiFetch from "@/lib/apiFetch"; import { ActionIcon, + Anchor, Button, Divider, + FileInput, Flex, Group, Input, @@ -10,7 +12,7 @@ import { Stack, Table, Title, - Tooltip, + Tooltip } from "@mantine/core"; import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import { IconEdit } from "@tabler/icons-react"; @@ -22,6 +24,7 @@ export default function DesaSetting() { const [btnDisable, setBtnDisable] = useState(false); const [btnLoading, setBtnLoading] = useState(false); const [opened, { open, close }] = useDisclosure(false); + const [img, setImg] = useState() const { data, mutate, isLoading } = useSWR("/", () => apiFetch.api["configuration-desa"].list.get(), ); @@ -39,7 +42,31 @@ export default function DesaSetting() { async function handleEdit() { try { setBtnLoading(true); - const res = await apiFetch.api["configuration-desa"].edit.post(dataEdit); + + let finalData = { ...dataEdit }; // ← buffer data terbaru + + if (dataEdit.name === "TTD") { + const resImg = await apiFetch.api.pengaduan.upload.post({ file: img }); + + if (resImg.status === 200) { + finalData = { + ...finalData, + value: resImg.data?.filename || "" + }; + + setDataEdit(finalData); // update state + } else { + return notification({ + title: "Error", + message: "Failed to upload image", + type: "error", + }); + } + } + + + const res = await apiFetch.api["configuration-desa"].edit.post(finalData); + if (res.status === 200) { mutate(); close(); @@ -67,6 +94,7 @@ export default function DesaSetting() { } } + function chooseEdit({ data, }: { @@ -100,18 +128,35 @@ export default function DesaSetting() { opened={opened} onClose={close} title={"Edit"} - centered overlayProps={{ backgroundOpacity: 0.55, blur: 3 }} > - - - onValidation({ kat: "value", value: e.target.value }) - } - /> - + { + dataEdit.name == "TTD" + ? + ( + + { setImg(e) }} + /> + + ) + : + ( + + + onValidation({ kat: "value", value: e.target.value }) + } + /> + + ) + } +