Compare commits
18 Commits
amalia/16-
...
amalia/23-
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bafb88086 | |||
| 777f2c04f1 | |||
| a81f6c4255 | |||
| 0f1b0196e7 | |||
| da86f5f10a | |||
| 91a3dfdb5d | |||
| 3904527c2a | |||
| ff0413be5a | |||
| fda2b0977a | |||
| 55fbf4836d | |||
| c897063eb5 | |||
| 84161db7f2 | |||
| a1766538b2 | |||
| d8cf7833a9 | |||
| c585d2481d | |||
| 18d3b40700 | |||
| baf00b1ba8 | |||
| dfc5c9144f |
310
bak/listPermission.json.txt
Normal file
310
bak/listPermission.json.txt
Normal file
@@ -0,0 +1,310 @@
|
||||
{
|
||||
"menus": [
|
||||
{
|
||||
"key": "dashboard",
|
||||
"label": "Dashboard",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "dashboard.view",
|
||||
"label": "Melihat Dashboard",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "pengaduan",
|
||||
"label": "Pengaduan",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pengaduan.view",
|
||||
"label": "Melihat List & Detail",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "pengaduan.antrian",
|
||||
"label": "Detail pengaduan dengan status antrian",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pengaduan.antrian.tolak",
|
||||
"label": "Menolak pengaduan",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "pengaduan.antrian.terima",
|
||||
"label": "Menerima pengaduan",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "pengaduan.diterima",
|
||||
"label": "Detail pengaduan dengan status diterima",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pengaduan.diterima.dikerjakan",
|
||||
"label": "Menegerjakan pengaduan",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "pengaduan.dikerjakan",
|
||||
"label": "Detail pengaduan dengan status dikerjakan",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pengaduan.dikerjakan.selesai",
|
||||
"label": "Menyelesaikan pengaduan",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "pelayanan",
|
||||
"label": "Pelayanan",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pelayanan.view",
|
||||
"label": "Melihat List & Detail",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "pelayanan.antrian",
|
||||
"label": "Detail pelayanan dengan status antrian",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pelayanan.antrian.tolak",
|
||||
"label": "Menolak pelayanan",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "pelayanan.antrian.terima",
|
||||
"label": "Menerima pelayanan",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "pelayanan.diterima",
|
||||
"label": "Detail pelayanan dengan status diterima",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "pelayanan.diterima.tolak",
|
||||
"label": "Menolak pelayanan",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "pelayanan.diterima.setujui",
|
||||
"label": "Menyetujui pelayanan",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "warga",
|
||||
"label": "Warga",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "warga.view",
|
||||
"label": "Melihat List & Detail",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting",
|
||||
"label": "Setting",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.profile",
|
||||
"label": "Profile",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.profile.view",
|
||||
"label": "View",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.profile.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.profile.password",
|
||||
"label": "Ubah Password",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting.user",
|
||||
"label": "User",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.user.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user.tambah",
|
||||
"label": "Tambah",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user.delete",
|
||||
"label": "Delete",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting.user_role",
|
||||
"label": "User Role",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.user_role.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user_role.tambah",
|
||||
"label": "Tambah",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user_role.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.user_role.delete",
|
||||
"label": "Delete",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pengaduan",
|
||||
"label": "Kategori Pengaduan",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.kategori_pengaduan.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pengaduan.tambah",
|
||||
"label": "Tambah",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pengaduan.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pengaduan.delete",
|
||||
"label": "Delete",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan",
|
||||
"label": "Kategori Pelayanan Surat",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.detail",
|
||||
"label": "View Detail",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.tambah",
|
||||
"label": "Tambah",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.delete",
|
||||
"label": "Delete",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "setting.desa",
|
||||
"label": "Desa",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "setting.desa.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.desa.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "api_key",
|
||||
"label": "API Key",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "api_key.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "credential",
|
||||
"label": "Credential",
|
||||
"default": true,
|
||||
"children": [
|
||||
{
|
||||
"key": "credential.view",
|
||||
"label": "View List",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -110,7 +110,8 @@ model CategoryPelayanan {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
syaratDokumen Json[]
|
||||
dataText String[]
|
||||
dataText String[] @default([])
|
||||
dataPelengkap Json[] @default([])
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -10,6 +10,7 @@ import FormKartuKeluarga from "./pages/darmasaba/form_kartu_keluarga";
|
||||
import FormLaporanSampah from "./pages/darmasaba/form_laporan_sampah";
|
||||
import FormSuratKeteranganPenghasilan from "./pages/darmasaba/form_surat_keterangan_penghasilan";
|
||||
import FormSuratKeteranganDomisiliOrganisasi from "./pages/darmasaba/form_surat_keterangan_domisili_organisasi";
|
||||
import UpdateDataSurat from "./pages/darmasaba/update_data_surat";
|
||||
import FormSuratKeteranganBelumKawin from "./pages/darmasaba/form_surat_keterangan_belum_kawin";
|
||||
import FormKeteranganKelahiran from "./pages/darmasaba/form_keterangan_kelahiran";
|
||||
import FormSuratKeteranganTempatUsaha from "./pages/darmasaba/form_surat_keterangan_tempat_usaha";
|
||||
@@ -69,6 +70,10 @@ export default function AppRoutes() {
|
||||
path="/darmasaba/surat-keterangan-domisili-organisasi"
|
||||
element={<FormSuratKeteranganDomisiliOrganisasi />}
|
||||
/>
|
||||
<Route
|
||||
path="/darmasaba/update-data-surat"
|
||||
element={<UpdateDataSurat />}
|
||||
/>
|
||||
<Route
|
||||
path="/darmasaba/surat-keterangan-belum-kawin"
|
||||
element={<FormSuratKeteranganBelumKawin />}
|
||||
|
||||
@@ -10,6 +10,7 @@ const clientRoutes = {
|
||||
"/darmasaba/laporan-sampah": "/darmasaba/laporan-sampah",
|
||||
"/darmasaba/surat-keterangan-penghasilan": "/darmasaba/surat-keterangan-penghasilan",
|
||||
"/darmasaba/surat-keterangan-domisili-organisasi": "/darmasaba/surat-keterangan-domisili-organisasi",
|
||||
"/darmasaba/update-data-surat": "/darmasaba/update-data-surat",
|
||||
"/darmasaba/surat-keterangan-belum-kawin": "/darmasaba/surat-keterangan-belum-kawin",
|
||||
"/darmasaba/keterangan-kelahiran": "/darmasaba/keterangan-kelahiran",
|
||||
"/darmasaba/surat-keterangan-tempat-usaha": "/darmasaba/surat-keterangan-tempat-usaha",
|
||||
|
||||
38
src/components/FullScreenLoading.tsx
Normal file
38
src/components/FullScreenLoading.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Center, Loader, Overlay, Stack, Text } from "@mantine/core";
|
||||
|
||||
type FullScreenLoadingProps = {
|
||||
visible: boolean;
|
||||
text?: string;
|
||||
};
|
||||
|
||||
export default function FullScreenLoading({
|
||||
visible,
|
||||
text = "Memproses data...",
|
||||
}: FullScreenLoadingProps) {
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<Overlay fixed blur={6} backgroundOpacity={0.3} zIndex={10000}>
|
||||
<Center h="100%">
|
||||
<Stack align="center" justify="center">
|
||||
<Loader size="lg" />
|
||||
<Text size="sm" c="dimmed">
|
||||
{text}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
</Overlay>
|
||||
);
|
||||
}
|
||||
|
||||
const overlayStyle: React.CSSProperties = {
|
||||
position: "fixed",
|
||||
inset: 0,
|
||||
zIndex: 9999,
|
||||
backdropFilter: "blur(6px)",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.6)",
|
||||
};
|
||||
|
||||
const contentStyle: React.CSSProperties = {
|
||||
flexDirection: "column",
|
||||
};
|
||||
@@ -11,10 +11,9 @@ import {
|
||||
Modal,
|
||||
Stack,
|
||||
Table,
|
||||
TagsInput,
|
||||
Text,
|
||||
Title,
|
||||
Tooltip,
|
||||
Tooltip
|
||||
} from "@mantine/core";
|
||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||
import { IconEdit, IconEye, IconPlus, IconTrash } from "@tabler/icons-react";
|
||||
@@ -44,13 +43,13 @@ export default function KategoriPelayananSurat({
|
||||
const [dataChoose, setDataChoose] = useState({
|
||||
id: "",
|
||||
name: "",
|
||||
syaratDokumen: [{ name: "", desc: "" }],
|
||||
dataText: [""],
|
||||
syaratDokumen: [{ key: "", name: "", desc: "" }],
|
||||
dataPelengkap: [{ key: "", name: "", desc: "" }],
|
||||
});
|
||||
const [dataTambah, setDataTambah] = useState({
|
||||
name: "",
|
||||
syaratDokumen: [{ name: "", desc: "" }],
|
||||
dataText: [""],
|
||||
syaratDokumen: [{ key: "", name: "", desc: "" }],
|
||||
dataPelengkap: [{ key: "", name: "", desc: "" }],
|
||||
});
|
||||
|
||||
useShallowEffect(() => {
|
||||
@@ -60,8 +59,8 @@ export default function KategoriPelayananSurat({
|
||||
async function handleCreate() {
|
||||
try {
|
||||
setBtnLoading(true);
|
||||
const cleanedDataText = dataTambah.dataText
|
||||
.map((v) => v.trim())
|
||||
const cleanedDataText = dataTambah.dataPelengkap
|
||||
.map((v) => v.name.trim())
|
||||
.filter((v) => v !== "");
|
||||
const cleanedSyarat = dataTambah.syaratDokumen
|
||||
.map((item) => ({
|
||||
@@ -82,8 +81,8 @@ export default function KategoriPelayananSurat({
|
||||
closeTambah();
|
||||
setDataTambah({
|
||||
name: "",
|
||||
syaratDokumen: [{ name: "", desc: "" }],
|
||||
dataText: [""],
|
||||
syaratDokumen: [{ key: "", name: "", desc: "" }],
|
||||
dataPelengkap: [{ key: "", name: "", desc: "" }],
|
||||
});
|
||||
notification({
|
||||
title: "Success",
|
||||
@@ -112,8 +111,8 @@ export default function KategoriPelayananSurat({
|
||||
async function handleEdit() {
|
||||
try {
|
||||
setBtnLoading(true);
|
||||
const cleanedDataText = dataChoose.dataText
|
||||
.map((v) => v.trim())
|
||||
const cleanedDataText = dataChoose.dataPelengkap
|
||||
.map((v) => v.name.trim())
|
||||
.filter((v) => v !== "");
|
||||
const cleanedSyarat = dataChoose.syaratDokumen
|
||||
.map((item) => ({
|
||||
@@ -191,7 +190,7 @@ export default function KategoriPelayananSurat({
|
||||
function handleAddSyarat() {
|
||||
setDataChoose({
|
||||
...dataChoose,
|
||||
syaratDokumen: [...dataChoose.syaratDokumen, { name: "", desc: "" }],
|
||||
syaratDokumen: [...dataChoose.syaratDokumen, { key: "", name: "", desc: "" }],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -204,7 +203,7 @@ export default function KategoriPelayananSurat({
|
||||
|
||||
function handleEditSyarat(
|
||||
index: number,
|
||||
data: { name: string; desc: string },
|
||||
data: { key: string; name: string; desc: string },
|
||||
) {
|
||||
setDataChoose({
|
||||
...dataChoose,
|
||||
@@ -217,7 +216,7 @@ export default function KategoriPelayananSurat({
|
||||
return (
|
||||
<>
|
||||
{/* Modal Edit */}
|
||||
<Modal
|
||||
{/* <Modal
|
||||
opened={opened}
|
||||
onClose={close}
|
||||
title={"Edit"}
|
||||
@@ -233,15 +232,85 @@ export default function KategoriPelayananSurat({
|
||||
}
|
||||
/>
|
||||
</Input.Wrapper>
|
||||
<TagsInput
|
||||
label="Data Pelengkap"
|
||||
placeholder="Tambah data pelengkap"
|
||||
splitChars={[","]}
|
||||
value={dataChoose.dataText}
|
||||
onChange={(value) =>
|
||||
setDataChoose({ ...dataChoose, dataText: value })
|
||||
}
|
||||
/>
|
||||
<Flex direction={"column"} gap={"md"}>
|
||||
<Group>
|
||||
<Text size="sm" c={"white"}>
|
||||
Data Pelengkap
|
||||
</Text>
|
||||
<Tooltip label="Tambah Data Pelengkap">
|
||||
<ActionIcon
|
||||
variant="light"
|
||||
size="sm"
|
||||
color="blue"
|
||||
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||
onClick={handleAddSyarat}
|
||||
>
|
||||
<IconPlus size={20} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
{dataChoose?.dataPelengkap?.map((v: any, i: number) => (
|
||||
<Grid
|
||||
key={i}
|
||||
style={{
|
||||
borderBottom: "1px solid gray",
|
||||
paddingBottom: "10px",
|
||||
}}
|
||||
>
|
||||
<Grid.Col
|
||||
span={1}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<Tooltip label="Delete Syarat Dokumen">
|
||||
<ActionIcon
|
||||
variant="light"
|
||||
size="sm"
|
||||
color="red"
|
||||
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||
onClick={() => {
|
||||
handleDeleteSyarat(i);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={20} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={5}>
|
||||
<Input.Wrapper label="Label">
|
||||
<Input
|
||||
value={v.name}
|
||||
onChange={(e) =>
|
||||
handleEditSyarat(i, {
|
||||
key: v.key,
|
||||
name: e.target.value,
|
||||
desc: v.desc,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Input.Wrapper>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Input.Wrapper label="Deskripsi">
|
||||
<Input
|
||||
value={v.desc}
|
||||
onChange={(e) =>
|
||||
handleEditSyarat(i, {
|
||||
key: v.key,
|
||||
name: v.name,
|
||||
desc: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Input.Wrapper>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
))}
|
||||
</Flex>
|
||||
|
||||
<Flex direction={"column"} gap={"md"}>
|
||||
<Group>
|
||||
<Text size="sm" c={"white"}>
|
||||
@@ -290,11 +359,12 @@ export default function KategoriPelayananSurat({
|
||||
</Tooltip>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={5}>
|
||||
<Input.Wrapper label="Nama">
|
||||
<Input.Wrapper label="Label">
|
||||
<Input
|
||||
value={v.name}
|
||||
onChange={(e) =>
|
||||
handleEditSyarat(i, {
|
||||
key: v.key,
|
||||
name: e.target.value,
|
||||
desc: v.desc,
|
||||
})
|
||||
@@ -308,6 +378,7 @@ export default function KategoriPelayananSurat({
|
||||
value={v.desc}
|
||||
onChange={(e) =>
|
||||
handleEditSyarat(i, {
|
||||
key: v.key,
|
||||
name: v.name,
|
||||
desc: e.target.value,
|
||||
})
|
||||
@@ -328,10 +399,10 @@ export default function KategoriPelayananSurat({
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</Modal> */}
|
||||
|
||||
{/* Modal Tambah */}
|
||||
<Modal
|
||||
{/* <Modal
|
||||
opened={openedTambah}
|
||||
onClose={closeTambah}
|
||||
title={"Tambah"}
|
||||
@@ -347,15 +418,6 @@ export default function KategoriPelayananSurat({
|
||||
}
|
||||
/>
|
||||
</Input.Wrapper>
|
||||
<TagsInput
|
||||
label="Data Pelengkap"
|
||||
placeholder="Tambah data pelengkap"
|
||||
splitChars={[","]}
|
||||
value={dataTambah.dataText}
|
||||
onChange={(value) =>
|
||||
setDataTambah({ ...dataTambah, dataText: value })
|
||||
}
|
||||
/>
|
||||
<Flex direction={"column"} gap={"md"}>
|
||||
<Group>
|
||||
<Text size="sm" c={"white"}>
|
||||
@@ -372,7 +434,7 @@ export default function KategoriPelayananSurat({
|
||||
...dataTambah,
|
||||
syaratDokumen: [
|
||||
...dataTambah.syaratDokumen,
|
||||
{ name: "", desc: "" },
|
||||
{ key: "", name: "", desc: "" },
|
||||
],
|
||||
});
|
||||
}}
|
||||
@@ -465,7 +527,7 @@ export default function KategoriPelayananSurat({
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</Modal> */}
|
||||
|
||||
{/* Modal Delete */}
|
||||
<Modal
|
||||
@@ -524,8 +586,8 @@ export default function KategoriPelayananSurat({
|
||||
Data Pelengkap
|
||||
</Text>
|
||||
<List>
|
||||
{dataChoose?.dataText?.map((v: any) => (
|
||||
<List.Item key={v.id}>{v}</List.Item>
|
||||
{dataChoose?.dataPelengkap?.map((v: any) => (
|
||||
<List.Item key={v.id}>{v.name}</List.Item>
|
||||
))}
|
||||
</List>
|
||||
</Flex>
|
||||
@@ -538,7 +600,7 @@ export default function KategoriPelayananSurat({
|
||||
<Title order={4} c="gray.2">
|
||||
Kategori Pelayanan Surat
|
||||
</Title>
|
||||
{permissions.includes("setting.kategori_pelayanan.tambah") && (
|
||||
{/* {permissions.includes("setting.kategori_pelayanan.tambah") && (
|
||||
<Tooltip label="Tambah Kategori Pelayanan Surat">
|
||||
<Button
|
||||
variant="light"
|
||||
@@ -548,7 +610,7 @@ export default function KategoriPelayananSurat({
|
||||
Tambah
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
)} */}
|
||||
</Flex>
|
||||
<Divider my={0} />
|
||||
<Stack gap={"md"}>
|
||||
@@ -579,7 +641,7 @@ export default function KategoriPelayananSurat({
|
||||
<IconEye size={20} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
{/* <Tooltip
|
||||
label={
|
||||
permissions.includes(
|
||||
"setting.kategori_pelayanan.edit",
|
||||
@@ -604,7 +666,7 @@ export default function KategoriPelayananSurat({
|
||||
>
|
||||
<IconEdit size={20} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Tooltip> */}
|
||||
<Tooltip
|
||||
label={
|
||||
permissions.includes(
|
||||
|
||||
45
src/components/SuccessPengajuanSurat.tsx
Normal file
45
src/components/SuccessPengajuanSurat.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Badge, Button, Card, Center, Stack, Text, Title } from "@mantine/core";
|
||||
import { IconCheck } from "@tabler/icons-react";
|
||||
|
||||
type SuccessPengajuanProps = {
|
||||
noPengajuan: string;
|
||||
onClose?: () => void;
|
||||
category?: 'create' | 'update';
|
||||
};
|
||||
|
||||
export default function SuccessPengajuan({
|
||||
noPengajuan,
|
||||
onClose,
|
||||
category
|
||||
}: SuccessPengajuanProps) {
|
||||
return (
|
||||
<Center h="100vh">
|
||||
<Card shadow="md" radius="md" p="xl" withBorder maw={520} w="100%">
|
||||
<Stack align="center" gap="md">
|
||||
<IconCheck size={56} color="green" />
|
||||
|
||||
<Title order={3} ta="center">
|
||||
{category == 'create' ? 'Pengajuan Berhasil Dibuat' : 'Pengajuan Berhasil Diupdate'}
|
||||
</Title>
|
||||
|
||||
<Text ta="center" size="sm" c="dimmed">
|
||||
{category == 'create' ? 'Pengajuan layanan surat sudah dibuat dengan nomor:' : 'Pengajuan layanan surat sudah diupdate dengan nomor:'}
|
||||
</Text>
|
||||
|
||||
<Badge size="xl" variant="light" color="green">
|
||||
{noPengajuan}
|
||||
</Badge>
|
||||
|
||||
<Text ta="center" size="sm">
|
||||
Nomor ini akan digunakan untuk mengakses dan memantau status
|
||||
pengajuan surat Anda.
|
||||
</Text>
|
||||
|
||||
<Button fullWidth mt="md" onClick={onClose}>
|
||||
Selesai
|
||||
</Button>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ export default function SKBedaBiodataDiri({ data }: { data: any }) {
|
||||
const getValue = (jenis: string) =>
|
||||
_.upperFirst(
|
||||
data.surat.dataText.find((item: any) => item.jenis === jenis)?.value ||
|
||||
"",
|
||||
"",
|
||||
);
|
||||
|
||||
const loadImage = async () => {
|
||||
@@ -108,12 +108,12 @@ export default function SKBedaBiodataDiri({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Tempat/Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
@@ -144,36 +144,38 @@ export default function SKBedaBiodataDiri({ data }: { data: any }) {
|
||||
<table style={{ width: "100%", marginTop: "5px" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>1. Nama</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("nama")}</td>
|
||||
<td style={{ width: "160px" }}>1. {getValue("data_dokumen")}</td>
|
||||
<td style={{ width: "10px" }}></td>
|
||||
<td>
|
||||
{/* {getValue("nama")} */}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tertulis pada dokumen A</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tertulis pada dokumen a")}</td>
|
||||
<td>{getValue("dokumen_a")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tertulis pada dokumen B</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tertulis pada dokumen b")}</td>
|
||||
<td>{getValue("dokumen_b")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: "15px" }}>
|
||||
{/* <div style={{ marginTop: "15px" }}>
|
||||
<table style={{ width: "100%", marginTop: "5px" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>2. Tempat/Tanggal Lahir</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{getValue("tempat_lahir")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tertulis pada dokumen A</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tertulis pada dokumen a")}</td>
|
||||
<td>{getValue("dokumen_a")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tertulis pada dokumen B</td>
|
||||
@@ -204,7 +206,7 @@ export default function SKBedaBiodataDiri({ data }: { data: any }) {
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div style={{ marginTop: "15px" }}>
|
||||
Perbedaan tersebut terjadi karena{" "}
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function SKBelumKawin({ data }: { data: any }) {
|
||||
const getValue = (jenis: string) =>
|
||||
_.upperFirst(
|
||||
data.surat.dataText.find((item: any) => item.jenis === jenis)?.value ||
|
||||
"",
|
||||
"",
|
||||
);
|
||||
|
||||
const loadImage = async () => {
|
||||
@@ -87,12 +87,12 @@ export default function SKBelumKawin({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Tempat/Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Agama</td>
|
||||
|
||||
@@ -95,27 +95,27 @@ export default function SKDomisiliOrganisasi({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>Nama Organisasi</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("nama")}</td>
|
||||
<td>{getValue("nama_organisasi")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Organisasi</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_organisasi")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{getValue("alamat_organisasi")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nomor Telepon</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("negara")}</td>
|
||||
<td>{getValue("no_telepon")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nama Pimpinan</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("agama")}</td>
|
||||
<td>{getValue("nama_pimpinan")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -78,32 +78,32 @@ export default function SKKelahiran({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "200px" }}>Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tanggal lahir anak")}</td>
|
||||
<td>{getValue("tanggal_lahir_anak")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pukul</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("pukul lahir anak")}</td>
|
||||
<td>{getValue("pukul_lahir")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat Kelahiran</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat lahir anak")}</td>
|
||||
<td>{getValue("tempat_lahir")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin anak")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Anak ke</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("anak ke")}</td>
|
||||
<td>{getValue("anak_ke")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nama Anak</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nama anak")}</td>
|
||||
<td>{getValue("nama_anak")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -117,27 +117,27 @@ export default function SKKelahiran({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "200px" }}>Nama Lengkap Ibu</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nama ibu")}</td>
|
||||
<td>{getValue("nama_ibu")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nik ibu")}</td>
|
||||
<td>{getValue("nik_ibu")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat & Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir ibu")}</td>
|
||||
<td>{`${getValue("tempat_lahir_ibu")}, ${getValue("tanggal_lahir_ibu")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("pekerjaan ibu")}</td>
|
||||
<td>{getValue("pekerjaan_ibu")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat ibu")}</td>
|
||||
<td>{getValue("alamat_ibu")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -151,27 +151,27 @@ export default function SKKelahiran({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "200px" }}>Nama Lengkap Ayah</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nama ayah")}</td>
|
||||
<td>{getValue("nama_ayah")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nik ayah")}</td>
|
||||
<td>{getValue("nik_ayah")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat & Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir ayah")}</td>
|
||||
<td>{`${getValue("tempat_lahir_ayah")}, ${"tanggal_lahir_ayah"}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("pekerjaan ayah")}</td>
|
||||
<td>{getValue("pekerjaan_ayah")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat ayah")}</td>
|
||||
<td>{getValue("alamat_ayah")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -185,17 +185,17 @@ export default function SKKelahiran({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "200px" }}>Nama Pelapor</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nama pelapor")}</td>
|
||||
<td>{getValue("nama_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hubungan dengan Anak</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("hubungan pelapor")}</td>
|
||||
<td>{getValue("hubungan_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat pelapor")}</td>
|
||||
<td>{getValue("alamat_pelapor")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -71,12 +71,12 @@ export default function SKKelakuanBaik({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Tempat/Tgl Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Agama</td>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function SKKematian({ data }: { data: any }) {
|
||||
const getValue = (jenis: string) =>
|
||||
_.upperFirst(
|
||||
data.surat.dataText.find((item: any) => item.jenis === jenis)?.value ||
|
||||
"",
|
||||
"",
|
||||
);
|
||||
|
||||
const loadImage = async () => {
|
||||
@@ -71,27 +71,27 @@ export default function SKKematian({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>Nama</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("nama")}</td>
|
||||
<td>{getValue("nama_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nik")}</td>
|
||||
<td>{getValue("nik_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("pekerjaan")}</td>
|
||||
<td>{getValue("pekerjaan_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat")}</td>
|
||||
<td>{getValue("alamat_pelapor")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hubungan dengan almarhum/almarhumah</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("hubungan dengan almarhum")}</td>
|
||||
<td>{getValue("hubungan_pelapor")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -104,32 +104,32 @@ export default function SKKematian({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>Nama</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("nama")}</td>
|
||||
<td>{getValue("nama_almarhum")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("nik")}</td>
|
||||
<td>{getValue("nik_almarhum")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin_almarhum")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat/Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir_almarhum")}, ${getValue("tanggal_lahir_almarhum")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Agama</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("agama")}</td>
|
||||
<td>{getValue("agama_almarhum")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat")}</td>
|
||||
<td>{getValue("alamat_almarhum")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -142,22 +142,22 @@ export default function SKKematian({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>Tanggal Kematian</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("tanggal kematian")}</td>
|
||||
<td>{getValue("tanggal_kematian")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Waktu Kematian</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("waktu kematian")}</td>
|
||||
<td>{getValue("waktu_kematian")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat Kematian</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat kematian")}</td>
|
||||
<td>{getValue("tempat_kematian")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Penyebab Kematian</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("penyebab kematian")}</td>
|
||||
<td>{getValue("penyebab_kematian")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -185,7 +185,7 @@ export default function SKKematian({ data }: { data: any }) {
|
||||
<br />
|
||||
<br />
|
||||
<br /> <br />
|
||||
<u>{getValue("nama")}</u> <br />
|
||||
<u>{getValue("nama_pelapor")}</u> <br />
|
||||
</div>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<br />
|
||||
|
||||
@@ -105,12 +105,12 @@ export default function SKPenghasilan({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat / Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
@@ -136,8 +136,7 @@ export default function SKPenghasilan({ data }: { data: any }) {
|
||||
<td style={{ width: "160px" }}>Penghasilan</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>
|
||||
Rp {getValue("penghasilan")} (
|
||||
{getValue("penghasilan terbilang")}) per bulan
|
||||
Rp. {getValue("penghasilan")} per bulan
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -147,7 +146,7 @@ export default function SKPenghasilan({ data }: { data: any }) {
|
||||
{/* KEPERLUAN */}
|
||||
<div style={{ marginTop: "20px" }}>
|
||||
Surat keterangan ini dibuat untuk keperluan:{" "}
|
||||
<b>{getValue("alasan permohonan")}</b>.
|
||||
<b>{getValue("alasan")}</b>.
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: "20px" }}>
|
||||
|
||||
@@ -66,12 +66,12 @@ export default function SKTempatUsaha({ data }: { data: any }) {
|
||||
|
||||
{/* DATA WARGA */}
|
||||
<div>
|
||||
<Row label="Nama Pemilik Usaha" value={getValue("nama")} />
|
||||
<Row label="Nama Pemilik Usaha" value={getValue("nama_pemilik")} />
|
||||
<Row
|
||||
label="Tempat/Tanggal Lahir"
|
||||
value={getValue("tempat tanggal lahir")}
|
||||
value={`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}
|
||||
/>
|
||||
<Row label="Alamat Pemilik Usaha" value={getValue("alamat")} />
|
||||
<Row label="Alamat Pemilik Usaha" value={getValue("alamat_pemilik")} />
|
||||
<Row label="Nomor KTP" value={getValue("nik")} />
|
||||
</div>
|
||||
|
||||
@@ -83,23 +83,23 @@ export default function SKTempatUsaha({ data }: { data: any }) {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Row label="Nama Usaha" value={getValue("nama usaha")} />
|
||||
<Row label="Bidang Usaha" value={getValue("bidang usaha")} />
|
||||
<Row label="Alamat Usaha" value={getValue("alamat usaha")} />
|
||||
<Row label="Nama Usaha" value={getValue("nama_usaha")} />
|
||||
<Row label="Bidang Usaha" value={getValue("bidang_usaha")} />
|
||||
<Row label="Alamat Usaha" value={getValue("alamat_usaha")} />
|
||||
<Row
|
||||
label="Status Tempat Usaha"
|
||||
value={getValue("status tempat usaha")}
|
||||
value={getValue("status_tempat")}
|
||||
/>
|
||||
<Row
|
||||
label="Luas Tempat Usaha"
|
||||
value={getValue("luas tempat usaha")}
|
||||
value={getValue("luas_usaha")}
|
||||
/>
|
||||
<Row label="Jumlah Karyawan" value={getValue("jumlah karyawan")} />
|
||||
<Row label="Jumlah Karyawan" value={getValue("jumlah_karyawan")} />
|
||||
</div>
|
||||
|
||||
<p style={{ textAlign: "justify" }}>
|
||||
Surat keterangan ini dibuat untuk keperluan{" "}
|
||||
<b>{getValue("alasan permohonan")}.</b>
|
||||
<b>{getValue("tujuan")}.</b>
|
||||
</p>
|
||||
|
||||
<p style={{ textAlign: "justify" }}>
|
||||
|
||||
@@ -66,13 +66,13 @@ export default function SKTidakMampu({ data }: { data: any }) {
|
||||
|
||||
{/* DATA WARGA */}
|
||||
<div>
|
||||
<Row label="NIK" value={getValue("nik")} />
|
||||
<Row label="Nama" value={getValue("nama")} />
|
||||
<Row
|
||||
label="Tempat Tgl Lahir"
|
||||
value={getValue("tempat tanggal lahir")}
|
||||
value={`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}
|
||||
/>
|
||||
<Row label="Alamat" value={getValue("alamat")} />
|
||||
<Row label="NIK" value={getValue("nik")} />
|
||||
</div>
|
||||
|
||||
<br />
|
||||
@@ -80,7 +80,7 @@ export default function SKTidakMampu({ data }: { data: any }) {
|
||||
<p style={{ textAlign: "justify" }}>
|
||||
Orang tersebut benar-benar penduduk desa {data.setting.desaNama} dan
|
||||
termasuk keluarga tidak mampu. Surat keterangan ini dipergunakan untuk
|
||||
<b>{getValue("alasan permohonan")}.</b>
|
||||
<b>{getValue("alasan")}.</b>
|
||||
</p>
|
||||
|
||||
<p style={{ textAlign: "justify" }}>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function SKUsaha({ data }: { data: any }) {
|
||||
const getValue = (jenis: string) =>
|
||||
_.upperFirst(
|
||||
data.surat.dataText.find((item: any) => item.jenis === jenis)?.value ||
|
||||
"",
|
||||
"",
|
||||
);
|
||||
|
||||
const loadImage = async () => {
|
||||
@@ -105,12 +105,12 @@ export default function SKUsaha({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("jenis kelamin")}</td>
|
||||
<td>{getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat / Tanggal Lahir</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("tempat tanggal lahir")}</td>
|
||||
<td>{`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Warga Negara</td>
|
||||
@@ -125,7 +125,7 @@ export default function SKUsaha({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td>Status</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("status perkawinan")}</td>
|
||||
<td>{getValue("status_perkawinan")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
@@ -173,12 +173,12 @@ export default function SKUsaha({ data }: { data: any }) {
|
||||
<tr>
|
||||
<td style={{ width: "160px" }}>Jenis Usaha</td>
|
||||
<td style={{ width: "10px" }}>:</td>
|
||||
<td>{getValue("jenis usaha")}</td>
|
||||
<td>{getValue("jenis_usaha")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat Usaha</td>
|
||||
<td>:</td>
|
||||
<td>{getValue("alamat usaha")}</td>
|
||||
<td>{getValue("alamat_usaha")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -88,26 +88,26 @@ export default function SKYatim({ data }: { data: any }) {
|
||||
|
||||
<table style={{ width: "100%", marginTop: "5px" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>: {getValue("nik")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{ width: "180px" }}>Nama</td>
|
||||
<td>: {getValue("nama")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tempat/Tanggal Lahir</td>
|
||||
<td>: {getValue("tempat tanggal lahir")}</td>
|
||||
<td>: {`${getValue("tempat_lahir")}, ${getValue("tanggal_lahir")}`}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jenis Kelamin</td>
|
||||
<td>: {getValue("jenis kelamin")}</td>
|
||||
<td>: {getValue("jenis_kelamin")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alamat</td>
|
||||
<td>: {getValue("alamat")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NIK</td>
|
||||
<td>: {getValue("nik")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pekerjaan</td>
|
||||
<td>: {getValue("pekerjaan")}</td>
|
||||
@@ -133,11 +133,11 @@ export default function SKYatim({ data }: { data: any }) {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ width: "180px" }}>Nama Ayah</td>
|
||||
<td>: {getValue("nama ayah")}</td>
|
||||
<td>: {getValue("nama_ayah")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Status</td>
|
||||
<td>: {getValue("status ayah")}</td>
|
||||
<td>: {getValue("status_ayah")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -151,11 +151,11 @@ export default function SKYatim({ data }: { data: any }) {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ width: "180px" }}>Nama Ibu</td>
|
||||
<td>: {getValue("nama ibu")}</td>
|
||||
<td>: {getValue("nama_ibu")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Status</td>
|
||||
<td>: {getValue("status ibu")}</td>
|
||||
<td>: {getValue("status_ibu")}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -3,107 +3,391 @@ export const categoryPelayananSurat = [
|
||||
id: "skbedabiodata",
|
||||
name: "Surat Keterangan Beda Biodata Diri",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas di Wilayah Masing-masing" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" },
|
||||
{ name: "dokumen yang beda", desc: "Fotokopi dokumen bersangkutan yang terdapat perbedaan biodata diri, misalnya: Sertifikat Tanah, Ijazah, Polis Asuransi, dan lainnya." }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas di Wilayah Masing-masing"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "dokumen_beda",
|
||||
name: "Dokumen Pendukung",
|
||||
desc: "Fotokopi dokumen yang terdapat perbedaan biodata (ijazah, sertifikat, dll)"
|
||||
}
|
||||
],
|
||||
dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "pekerjaan", "dokumen", "tertulis pada dokumen a", "tertulis pada dokumen b"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik", name: "NIK", desc: "Nomor Induk Kependudukan" },
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama sesuai KTP" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir pemohon" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir pemohon" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin pemohon" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat lengkap tempat tinggal" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan pemohon" },
|
||||
{ key: "dokumen", name: "Nama Dokumen", desc: "Jenis dokumen yang mengalami perbedaan biodata (cth : ijazah, sertifikat, dll)" },
|
||||
{ key: "data_dokumen", name: "Data Dokumen", desc: "Data dokumen yg berbeda (cth : nama, tempat lahir, tanggal lahir, jenis kelamin, alamat, pekerjaan)" },
|
||||
{ key: "dokumen_a", name: "Data pada Dokumen A", desc: "Data biodata yang tertulis pada dokumen pertama" },
|
||||
{ key: "dokumen_b", name: "Data pada Dokumen B", desc: "Data biodata yang tertulis pada dokumen kedua" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skbelumkawin",
|
||||
name: "Surat Keterangan Belum Kawin",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" },
|
||||
{ name: "akta cerai", desc: "Fotokopi Akta Cerai bagi yang berstatus janda/duda" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "akta_cerai",
|
||||
name: "Akta Cerai",
|
||||
desc: "Fotokopi akta cerai (jika berstatus janda/duda)"
|
||||
}
|
||||
],
|
||||
dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "agama", "pekerjaan"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik", name: "NIK", desc: "Nomor Induk Kependudukan" },
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama sesuai KTP" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir pemohon" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir pemohon" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin pemohon" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat tempat tinggal" },
|
||||
{ key: "agama", name: "Agama", desc: "Agama pemohon" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan pemohon" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skdomisiliorganisasi",
|
||||
name: "Surat Keterangan Domisili Organisasi",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ 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" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "skt_organisasi",
|
||||
name: "SKT Organisasi",
|
||||
desc: "Fotokopi SKT Organisasi atau pengukuhan kelompok"
|
||||
},
|
||||
{
|
||||
key: "susunan_pengurus",
|
||||
name: "Susunan Pengurus",
|
||||
desc: "Susunan pengurus lengkap dengan kop organisasi"
|
||||
}
|
||||
],
|
||||
dataText: ["nama organisasi", "jenis organisasi", "alamat organisasi/sekretariat", "no telepon", "nama pimpinan", "keperluan"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nama_organisasi", name: "Nama Organisasi", desc: "Nama resmi organisasi" },
|
||||
{ key: "jenis_organisasi", name: "Jenis Organisasi", desc: "Jenis atau bentuk organisasi" },
|
||||
{ key: "alamat_organisasi", name: "Alamat Organisasi", desc: "Alamat sekretariat organisasi" },
|
||||
{ key: "no_telepon", name: "Nomor Telepon", desc: "Nomor telepon organisasi" },
|
||||
{ key: "nama_pimpinan", name: "Nama Pimpinan", desc: "Nama pimpinan organisasi" },
|
||||
{ key: "keperluan", name: "Keperluan", desc: "Keperluan pembuatan surat" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skkelahiran",
|
||||
name: "Surat Keterangan Kelahiran",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "surat lahir", desc: "Fotokopi Surat Keterangan Lahir dari Bidan/Dokter (jika ada)" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "surat_lahir",
|
||||
name: "Surat Keterangan Lahir",
|
||||
desc: "Surat keterangan lahir dari bidan/dokter (jika ada)"
|
||||
}
|
||||
],
|
||||
dataText: ["nama ayah", "nama ibu", "nama anak", "tanggal lahir anak", "pukul lahir anak", "tempat lahir anak", "jenis kelamin anak", "anak ke", "nik ibu", "tempat tanggal lahir ibu", "pekerjaan ibu", "alamat ibu", "nik ayah", "tempat tanggal lahir ayah", "pekerjaan ayah", "alamat ayah", "nama pelapor", "hubungan pelapor", "alamat pelapor"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nama_anak", name: "Nama Anak", desc: "Nama bayi/anak" },
|
||||
{ key: "tanggal_lahir_anak", name: "Tanggal Lahir Anak", desc: "Tanggal lahir anak" },
|
||||
{ key: "pukul_lahir", name: "Pukul Lahir", desc: "Waktu kelahiran anak" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat kelahiran anak" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin Anak", desc: "Jenis kelamin anak" },
|
||||
{ key: "anak_ke", name: "Anak Ke-", desc: "Urutan kelahiran anak" },
|
||||
{ key: "nik_ibu", name: "NIK Ibu", desc: "NIK ibu kandung" },
|
||||
{ key: "nama_ibu", name: "Nama Ibu", desc: "Nama lengkap ibu" },
|
||||
{ key: "tempat_lahir_ibu", name: "Tempat Lahir Ibu", desc: "Tempat lahir ibu kandung" },
|
||||
{ key: "tanggal_lahir_ibu", name: "Tanggal Lahir Ibu", desc: "Tanggal lahir ibu kandung" },
|
||||
{ key: "pekerjaan_ibu", name: "Pekerjaan Ibu", desc: "Pekerjaan ibu kandung" },
|
||||
{ key: "alamat_ibu", name: "Alamat Ibu", desc: "Alamat ibu kandung" },
|
||||
{ key: "nama_ayah", name: "Nama Ayah", desc: "Nama lengkap ayah" },
|
||||
{ key: "nik_ayah", name: "NIK Ayah", desc: "NIK ayah kandung" },
|
||||
{ key: "tempat_lahir_ayah", name: "Tempat Lahir Ayah", desc: "Tempat lahir ayah kandung" },
|
||||
{ key: "tanggal_lahir_ayah", name: "Tanggal Lahir Ayah", desc: "Tanggal lahir ayah kandung" },
|
||||
{ key: "pekerjaan_ayah", name: "Pekerjaan Ayah", desc: "Pekerjaan ayah kandung" },
|
||||
{ key: "alamat_ayah", name: "Alamat Ayah", desc: "Alamat ayah kandung" },
|
||||
{ key: "nama_pelapor", name: "Nama Pelapor", desc: "Nama pihak yang melaporkan" },
|
||||
{ key: "hubungan_pelapor", name: "Hubungan Pelapor", desc: "Hubungan pelapor dengan anak" },
|
||||
{ key: "alamat_pelapor", name: "Alamat Pelapor", desc: "Alamat pelapor" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skkelakuanbaik",
|
||||
name: "Surat Keterangan Kelakuan Baik (Pengantar SKCK)",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
}
|
||||
],
|
||||
dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "agama", "alamat", "pekerjaan", "polsek"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik", name: "NIK", desc: "Nomor Induk Kependudukan" },
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama sesuai KTP" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin pemohon" },
|
||||
{ key: "agama", name: "Agama", desc: "Agama pemohon" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat tempat tinggal" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan pemohon" },
|
||||
{ key: "polsek", name: "Polsek Tujuan", desc: "Polsek tujuan pembuatan SKCK" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skkematian",
|
||||
name: "Surat Keterangan Kematian",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" },
|
||||
{ name: "surat kematian", desc: "Surat Keterangan Kematian dari Rumah Sakit/Dokter (jika ada)" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "surat_kematian",
|
||||
name: "Surat Keterangan Kematian",
|
||||
desc: "Surat keterangan kematian dari rumah sakit/dokter (jika ada)"
|
||||
}
|
||||
],
|
||||
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"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik_pelapor", name: "NIK Pelapor", desc: "Nomor Induk Kependudukan pelapor" },
|
||||
{ key: "nama_pelapor", name: "Nama Pelapor", desc: "Nama lengkap pelapor" },
|
||||
{ key: "pekerjaan_pelapor", name: "Pekerjaan Pelapor", desc: "Pekerjaan pelapor" },
|
||||
{ key: "alamat_pelapor", name: "Alamat Pelapor", desc: "Alamat tempat tinggal pelapor" },
|
||||
{ key: "hubungan_pelapor", name: "Hubungan dengan Almarhum", desc: "Hubungan pelapor dengan almarhum" },
|
||||
{ key: "nama_almarhum", name: "Nama Almarhum", desc: "Nama lengkap almarhum" },
|
||||
{ key: "nik_almarhum", name: "NIK Almarhum", desc: "Nomor Induk Kependudukan almarhum" },
|
||||
{ key: "tempat_lahir_almarhum", name: "Tempat Lahir Almarhum", desc: "Tempat lahir almarhum" },
|
||||
{ key: "tanggal_lahir_almarhum", name: "Tanggal Lahir Almarhum", desc: "Tanggal lahir almarhum" },
|
||||
{ key: "alamat_almarhum", name: "Alamat Almarhum", desc: "Alamat terakhir almarhum" },
|
||||
{ key: "agama_almarhum", name: "Agama Almarhum", desc: "Agama almarhum" },
|
||||
{ key: "tanggal_kematian", name: "Tanggal Kematian", desc: "Tanggal meninggal dunia" },
|
||||
{ key: "waktu_kematian", name: "Waktu Kematian", desc: "Waktu meninggal dunia" },
|
||||
{ key: "tempat_kematian", name: "Tempat Kematian", desc: "Tempat meninggal dunia" },
|
||||
{ key: "penyebab_kematian", name: "Penyebab Kematian", desc: "Penyebab meninggal dunia" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skpenghasilan",
|
||||
name: "Surat Keterangan Penghasilan",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp ortu/kk", desc: "Fotokopi KTP orang tua atau Kartu Keluarga" },
|
||||
{ name: "surat pernyataan", desc: "Surat Pernyataan Penghasilan bermaterai" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_ortu_kk",
|
||||
name: "KTP Orang Tua / KK",
|
||||
desc: "Fotokopi KTP orang tua atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "surat_pernyataan",
|
||||
name: "Surat Pernyataan",
|
||||
desc: "Surat pernyataan penghasilan bermaterai"
|
||||
}
|
||||
],
|
||||
dataText: ["nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "pekerjaan", "penghasilan", "alasan permohonan"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama pemohon" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin pemohon" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat tempat tinggal" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan pemohon/orang tua" },
|
||||
{ key: "penghasilan", name: "Penghasilan", desc: "Jumlah penghasilan per bulan" },
|
||||
{ key: "alasan", name: "Alasan Permohonan", desc: "Alasan pengajuan surat penghasilan" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "sktempatusaha",
|
||||
name: "Surat Keterangan Tempat Usaha",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" },
|
||||
{ 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" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "foto_lokasi",
|
||||
name: "Foto Lokasi Usaha",
|
||||
desc: "Foto lokasi usaha dicetak dan distempel oleh Kelian"
|
||||
},
|
||||
{
|
||||
key: "dokumen_lahan",
|
||||
name: "Dokumen Lahan",
|
||||
desc: "SPPT, Sertifikat, atau surat sewa tempat usaha"
|
||||
}
|
||||
],
|
||||
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"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik", name: "NIK", desc: "Nomor Induk Kependudukan" },
|
||||
{ key: "nama_pemilik", name: "Nama Pemilik", desc: "Nama pemilik usaha" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir" },
|
||||
{ key: "alamat_pemilik", name: "Alamat Pemilik", desc: "Alamat pemilik usaha" },
|
||||
{ key: "nama_usaha", name: "Nama Usaha", desc: "Nama usaha" },
|
||||
{ key: "bidang_usaha", name: "Bidang Usaha", desc: "Bidang atau jenis usaha" },
|
||||
{ key: "alamat_usaha", name: "Alamat Usaha", desc: "Alamat lokasi usaha" },
|
||||
{ key: "status_tempat", name: "Status Tempat Usaha", desc: "Status kepemilikan tempat usaha" },
|
||||
{ key: "luas_usaha", name: "Luas Tempat Usaha", desc: "Luas tempat usaha (m²)" },
|
||||
{ key: "jumlah_karyawan", name: "Jumlah Karyawan", desc: "Jumlah tenaga kerja" },
|
||||
{ key: "tujuan", name: "Tujuan Pembuatan Surat", desc: "Tujuan pembuatan surat keterangan" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "sktidakmampu",
|
||||
name: "Surat Keterangan Tidak Mampu",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kia/kk", desc: "Fotokopi KTP, KIA, atau Kartu Keluarga" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kia_kk",
|
||||
name: "KTP / KIA / KK",
|
||||
desc: "Fotokopi KTP, KIA, atau Kartu Keluarga"
|
||||
}
|
||||
],
|
||||
dataText: ["nik", "nama", "tempat tanggal lahir", "alamat", "alasan permohonan"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{
|
||||
key: "nik",
|
||||
name: "NIK",
|
||||
desc: "Nomor Induk Kependudukan pemohon"
|
||||
},
|
||||
{
|
||||
key: "nama",
|
||||
name: "Nama Lengkap",
|
||||
desc: "Nama lengkap pemohon"
|
||||
},
|
||||
{
|
||||
key: "tempat_lahir",
|
||||
name: "Tempat Lahir",
|
||||
desc: "Tempat lahir pemohon"
|
||||
},
|
||||
{
|
||||
key: "tanggal_lahir",
|
||||
name: "Tanggal Lahir",
|
||||
desc: "Tanggal lahir pemohon"
|
||||
},
|
||||
{
|
||||
key: "alamat",
|
||||
name: "Alamat",
|
||||
desc: "Alamat tempat tinggal pemohon"
|
||||
},
|
||||
{
|
||||
key: "alasan",
|
||||
name: "Alasan Permohonan",
|
||||
desc: "Alasan pengajuan Surat Keterangan Tidak Mampu"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skusaha",
|
||||
name: "Surat Keterangan Usaha",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kk", desc: "Fotokopi KTP atau Kartu Keluarga" },
|
||||
{ name: "foto lokasi", desc: "Foto lokasi usaha dicetak dalam selembar kertas, diparaf dan distempel oleh Kelian" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kk",
|
||||
name: "KTP / KK",
|
||||
desc: "Fotokopi KTP atau Kartu Keluarga"
|
||||
},
|
||||
{
|
||||
key: "foto_lokasi",
|
||||
name: "Foto Lokasi Usaha",
|
||||
desc: "Foto lokasi usaha dicetak dan distempel oleh Kelian"
|
||||
}
|
||||
],
|
||||
dataText: ["nama", "jenis kelamin", "tempat tanggal lahir", "negara", "agama", "status perkawinan", "alamat", "pekerjaan", "jenis usaha", "alamat usaha"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama pemilik usaha" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin pemilik usaha" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir", desc: "Tempat lahir" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir", desc: "Tanggal lahir" },
|
||||
{ key: "negara", name: "Kewarganegaraan", desc: "Kewarganegaraan pemilik usaha" },
|
||||
{ key: "agama", name: "Agama", desc: "Agama pemilik usaha" },
|
||||
{ key: "status_perkawinan", name: "Status Perkawinan", desc: "Status perkawinan" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat tempat tinggal" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan pemilik usaha" },
|
||||
{ key: "jenis_usaha", name: "Jenis Usaha", desc: "Jenis usaha yang dijalankan" },
|
||||
{ key: "alamat_usaha", name: "Alamat Usaha", desc: "Alamat lokasi usaha" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "skyatimpiatu",
|
||||
name: "Surat Keterangan Yatim / Piatu / Yatim Piatu",
|
||||
syaratDokumen: [
|
||||
{ name: "pengantar kelian", desc: "Surat Pengantar Kelian Banjar Dinas" },
|
||||
{ name: "ktp/kia/kk", desc: "Fotokopi KTP, KIA, atau Kartu Keluarga" }
|
||||
{
|
||||
key: "pengantar_kelian",
|
||||
name: "Pengantar Kelian",
|
||||
desc: "Surat Pengantar Kelian Banjar Dinas"
|
||||
},
|
||||
{
|
||||
key: "ktp_kia_kk",
|
||||
name: "KTP / KIA / KK",
|
||||
desc: "Fotokopi KTP, KIA, atau Kartu Keluarga"
|
||||
}
|
||||
],
|
||||
dataText: ["nik", "nama", "tempat tanggal lahir", "jenis kelamin", "alamat", "pekerjaan", "nama ayah", "status ayah", "nama ibu", "status ibu"]
|
||||
dataText: [],
|
||||
dataPelengkap: [
|
||||
{ key: "nik", name: "NIK", desc: "Nomor Induk Kependudukan" },
|
||||
{ key: "nama", name: "Nama Lengkap", desc: "Nama anak" },
|
||||
{ key: "tempat_lahir", name: "Tempat Lahir Anak", desc: "Tempat lahir anak" },
|
||||
{ key: "tanggal_lahir", name: "Tanggal Lahir Anak", desc: "Tanggal lahir anak" },
|
||||
{ key: "jenis_kelamin", name: "Jenis Kelamin", desc: "Jenis kelamin anak" },
|
||||
{ key: "alamat", name: "Alamat", desc: "Alamat tempat tinggal" },
|
||||
{ key: "pekerjaan", name: "Pekerjaan", desc: "Pekerjaan (jika ada)" },
|
||||
{ key: "nama_ayah", name: "Nama Ayah", desc: "Nama ayah kandung" },
|
||||
{ key: "status_ayah", name: "Status Ayah", desc: "Status ayah (hidup / meninggal)" },
|
||||
{ key: "nama_ibu", name: "Nama Ibu", desc: "Nama ibu kandung" },
|
||||
{ key: "status_ibu", name: "Status Ibu", desc: "Status ibu (hidup / meninggal)" }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -246,16 +246,6 @@
|
||||
"label": "View Detail",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.tambah",
|
||||
"label": "Tambah",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.edit",
|
||||
"label": "Edit",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"key": "setting.kategori_pelayanan.delete",
|
||||
"label": "Delete",
|
||||
|
||||
@@ -1,331 +1,546 @@
|
||||
import FullScreenLoading from "@/components/FullScreenLoading";
|
||||
import notification from "@/components/notificationGlobal";
|
||||
import SuccessPengajuan from "@/components/SuccessPengajuanSurat";
|
||||
import apiFetch from "@/lib/apiFetch";
|
||||
import { fromSlug, toSlug } from "@/server/lib/slug_converter";
|
||||
import {
|
||||
ActionIcon,
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Container,
|
||||
Divider,
|
||||
Grid,
|
||||
Group,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Textarea,
|
||||
Tooltip
|
||||
ActionIcon,
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Container,
|
||||
Divider,
|
||||
FileInput,
|
||||
Flex,
|
||||
Grid,
|
||||
Group,
|
||||
Modal,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||
import {
|
||||
IconBuildingCommunity,
|
||||
IconInfoCircle,
|
||||
IconMapPin,
|
||||
IconUser
|
||||
IconBuildingCommunity,
|
||||
IconInfoCircle,
|
||||
IconUpload,
|
||||
IconUser,
|
||||
} from "@tabler/icons-react";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import useSWR from "swr";
|
||||
|
||||
// =========================
|
||||
// Reusable UI components
|
||||
// =========================
|
||||
type DataItem = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
type FormSurat = {
|
||||
kategoriId: string;
|
||||
nama: string;
|
||||
phone: string;
|
||||
dataPelengkap: DataItem[];
|
||||
syaratDokumen: DataItem[];
|
||||
};
|
||||
|
||||
export default function FormSurat() {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [noPengajuan, setNoPengajuan] = useState("");
|
||||
const [submitLoading, setSubmitLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const { search } = useLocation();
|
||||
const query = new URLSearchParams(search);
|
||||
const jenisSurat = query.get("jenis");
|
||||
const { data, mutate, isLoading } = useSWR("category-pelayanan-list", () =>
|
||||
apiFetch.api.pelayanan.category.get(),
|
||||
);
|
||||
const [jenisSuratFix, setJenisSuratFix] = useState({ name: "", id: "" });
|
||||
const [dataSurat, setDataSurat] = useState<any>({});
|
||||
const [formSurat, setFormSurat] = useState<FormSurat>({
|
||||
nama: "",
|
||||
phone: "",
|
||||
kategoriId: "",
|
||||
dataPelengkap: [],
|
||||
syaratDokumen: [],
|
||||
});
|
||||
|
||||
const listCategory = data?.data || [];
|
||||
|
||||
function onResetAll() {
|
||||
setNoPengajuan("");
|
||||
setSubmitLoading(false);
|
||||
setFormSurat({
|
||||
nama: "",
|
||||
phone: "",
|
||||
kategoriId: "",
|
||||
dataPelengkap: [],
|
||||
syaratDokumen: [],
|
||||
});
|
||||
}
|
||||
|
||||
function onGetJenisSurat() {
|
||||
try {
|
||||
if (!jenisSurat || jenisSurat == "null") {
|
||||
setJenisSuratFix({ name: "", id: "" });
|
||||
} else {
|
||||
const namaJenis = fromSlug(jenisSurat);
|
||||
const data = listCategory.find((item: any) => item.name == namaJenis);
|
||||
if (!data) return;
|
||||
setJenisSuratFix(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function getDetailJenisSurat() {
|
||||
try {
|
||||
const get: any = await apiFetch.api.pelayanan.category.detail.get({
|
||||
query: {
|
||||
id: jenisSuratFix.id,
|
||||
},
|
||||
});
|
||||
|
||||
setDataSurat(get.data);
|
||||
setFormSurat({
|
||||
kategoriId: jenisSuratFix.id,
|
||||
nama: "",
|
||||
phone: "",
|
||||
dataPelengkap: (get.data?.dataPelengkap || []).map(
|
||||
(item: { key: string }) => ({
|
||||
key: item.key,
|
||||
value: "",
|
||||
}),
|
||||
),
|
||||
syaratDokumen: (get.data?.syaratDokumen || []).map(
|
||||
(item: { key: string }) => ({
|
||||
key: item.key,
|
||||
value: "",
|
||||
}),
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
useShallowEffect(() => {
|
||||
mutate();
|
||||
}, []);
|
||||
|
||||
useShallowEffect(() => {
|
||||
if (listCategory.length > 0) {
|
||||
onGetJenisSurat();
|
||||
}
|
||||
}, [jenisSurat, listCategory]);
|
||||
|
||||
useShallowEffect(() => {
|
||||
if (jenisSuratFix.id != "") {
|
||||
getDetailJenisSurat();
|
||||
}
|
||||
}, [jenisSuratFix.id]);
|
||||
|
||||
function onChecking() {
|
||||
const isFormKosong = Object.values(formSurat).some((value) => {
|
||||
if (Array.isArray(value)) {
|
||||
return (
|
||||
value.length === 0 ||
|
||||
value.some(
|
||||
(item) =>
|
||||
typeof item.value === "string" && item.value.trim() === "",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
return value.trim() === "";
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (isFormKosong) {
|
||||
return notification({
|
||||
title: "Gagal",
|
||||
message: "Silahkan lengkapi form surat",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
open();
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
try {
|
||||
setSubmitLoading(true);
|
||||
// 🔥 CLONE state SEKALI
|
||||
let finalFormSurat = structuredClone(formSurat);
|
||||
|
||||
// 2️⃣ Upload satu per satu
|
||||
for (const itemUpload of finalFormSurat.syaratDokumen) {
|
||||
const updImg = await apiFetch.api.pengaduan.upload.post({
|
||||
file: itemUpload.value,
|
||||
folder: "syarat-dokumen",
|
||||
});
|
||||
|
||||
if (updImg.status === 200) {
|
||||
// 🔥 UPDATE OBJECT LOKAL (BUKAN STATE)
|
||||
finalFormSurat.syaratDokumen = updateArrayByKey(
|
||||
finalFormSurat.syaratDokumen,
|
||||
itemUpload.key,
|
||||
updImg.data?.filename || "",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 3️⃣ SET STATE SEKALI (optional, untuk UI)
|
||||
setFormSurat(finalFormSurat);
|
||||
|
||||
// 4️⃣ SUBMIT KE API
|
||||
const res = await apiFetch.api.pelayanan.create.post(finalFormSurat);
|
||||
|
||||
if (res.status === 200) {
|
||||
setNoPengajuan(res.data?.noPengajuan || "");
|
||||
} else {
|
||||
notification({
|
||||
title: "Gagal",
|
||||
message:
|
||||
"Pengajuan surat gagal dibuat, silahkan coba beberapa saat lagi",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification({
|
||||
title: "Gagal",
|
||||
message: "Server Error",
|
||||
type: "error",
|
||||
});
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function updateArrayByKey(
|
||||
list: DataItem[],
|
||||
targetKey: string,
|
||||
value: string,
|
||||
): DataItem[] {
|
||||
return list.map((item) =>
|
||||
item.key === targetKey ? { ...item, value } : item,
|
||||
);
|
||||
}
|
||||
|
||||
function validationForm({
|
||||
key,
|
||||
value,
|
||||
}: {
|
||||
key: "nama" | "phone" | "dataPelengkap" | "syaratDokumen";
|
||||
value: any;
|
||||
}) {
|
||||
if (key == "dataPelengkap" || key == "syaratDokumen") {
|
||||
setFormSurat((prev) => ({
|
||||
...prev,
|
||||
[key]: updateArrayByKey(prev[key], value.key, value.value),
|
||||
}));
|
||||
} else {
|
||||
setFormSurat({
|
||||
...formSurat,
|
||||
[key]: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Container size="md" w={"100%"} pb={"lg"}>
|
||||
<Modal
|
||||
opened={opened}
|
||||
onClose={close}
|
||||
title={"Konfirmasi"}
|
||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Text>
|
||||
Apakah anda yakin ingin mengirim pengajuan surat ini?
|
||||
</Text>
|
||||
<Group justify="center" grow>
|
||||
<Button variant="light" onClick={close}>
|
||||
Tidak
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
color="green"
|
||||
onClick={() => {
|
||||
onSubmit();
|
||||
close();
|
||||
}}
|
||||
>
|
||||
Ya
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
<FullScreenLoading visible={submitLoading} />
|
||||
{noPengajuan != "" ? (
|
||||
<SuccessPengajuan
|
||||
noPengajuan={noPengajuan}
|
||||
onClose={() => {
|
||||
onResetAll();
|
||||
navigate("/darmasaba/surat");
|
||||
}}
|
||||
category="create"
|
||||
/>
|
||||
)
|
||||
:
|
||||
<Box>
|
||||
<Stack gap="lg">
|
||||
<Group justify="space-between" align="center">
|
||||
<Group align="center">
|
||||
<IconBuildingCommunity size={28} />
|
||||
<div>
|
||||
<Text fw={800} size="xl">
|
||||
Layanan Pengajuan Surat Administrasi
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
Formulir resmi untuk mengajukan berbagai jenis surat
|
||||
administrasi desa/kelurahan secara online.
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
<Group>
|
||||
<Badge radius="sm">Form Length: 3 Sections</Badge>
|
||||
</Group>
|
||||
</Group>
|
||||
<Stack gap="lg">
|
||||
{/* Header Section */}
|
||||
<FormSection
|
||||
title="Pemohon"
|
||||
icon={<IconUser size={16} />}
|
||||
description="Informasi identitas pemohon"
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Nama" hint="Nama pemohon" />}
|
||||
placeholder="Budi Setiawan"
|
||||
value={formSurat.nama}
|
||||
onChange={(e) =>
|
||||
validationForm({ key: "nama", value: e.target.value })
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Nomor Telephone"
|
||||
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
|
||||
/>
|
||||
}
|
||||
placeholder="08123456789"
|
||||
value={formSurat.phone}
|
||||
onChange={(e) =>
|
||||
validationForm({ key: "phone", value: e.target.value })
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={12}>
|
||||
<Select
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Jenis Surat"
|
||||
hint="Jenis surat yang ingin diajukan"
|
||||
/>
|
||||
}
|
||||
placeholder="Pilih jenis surat"
|
||||
data={listCategory.map((item: any) => ({
|
||||
value: item.name,
|
||||
label: item.name,
|
||||
}))}
|
||||
value={jenisSuratFix.name}
|
||||
onChange={(value) => {
|
||||
const slug = toSlug(String(value));
|
||||
navigate("/darmasaba/surat?jenis=" + slug);
|
||||
}}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
{jenisSuratFix.id != "" && dataSurat && dataSurat.dataPelengkap && (
|
||||
<>
|
||||
<FormSection
|
||||
title="Data Pelengkap"
|
||||
description="Data pelengkap yang diperlukan"
|
||||
>
|
||||
<Grid>
|
||||
{dataSurat.dataPelengkap.map((item: any, index: number) => (
|
||||
<Grid.Col span={6} key={index}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel label={item.name} hint={item.desc} />
|
||||
}
|
||||
placeholder={item.name}
|
||||
onChange={(e) =>
|
||||
validationForm({
|
||||
key: "dataPelengkap",
|
||||
value: { key: item.key, value: e.target.value },
|
||||
})
|
||||
}
|
||||
value={
|
||||
formSurat.dataPelengkap.find(
|
||||
(n: any) => n.key == item.key,
|
||||
)?.value
|
||||
}
|
||||
/>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
<FormSection
|
||||
title="Syarat Dokumen"
|
||||
description="Syarat dokumen yang diperlukan"
|
||||
>
|
||||
<Grid>
|
||||
{dataSurat.syaratDokumen.map((item: any, index: number) => (
|
||||
<Grid.Col span={6} key={index}>
|
||||
<FileInputWrapper
|
||||
label={item.desc}
|
||||
placeholder={"Upload file "}
|
||||
accept="image/*,application/pdf"
|
||||
onChange={(file) =>
|
||||
validationForm({
|
||||
key: "syaratDokumen",
|
||||
value: { key: item.key, value: file },
|
||||
})
|
||||
}
|
||||
name={item.name}
|
||||
/>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
{/* Actions */}
|
||||
<Group justify="right" mt="md">
|
||||
{/* <Button variant="default" onClick={() => { }}>
|
||||
Reset
|
||||
</Button> */}
|
||||
<Button onClick={onChecking}>Kirim</Button>
|
||||
</Group>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
}
|
||||
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
function FieldLabel({ label, hint }: { label: string; hint?: string }) {
|
||||
return (
|
||||
<Group justify="apart" gap="xs" align="center">
|
||||
<Text fw={600}>{label}</Text>
|
||||
{hint && (
|
||||
<Tooltip label={hint} withArrow>
|
||||
<ActionIcon size={24} variant="subtle">
|
||||
<IconInfoCircle size={16} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Group>
|
||||
);
|
||||
return (
|
||||
<Group justify="apart" gap="xs" align="center">
|
||||
<Text fw={600}>{label}</Text>
|
||||
{hint && (
|
||||
<Tooltip label={hint} withArrow>
|
||||
<ActionIcon size={24} variant="subtle">
|
||||
<IconInfoCircle size={16} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
function FormSection({
|
||||
title,
|
||||
icon,
|
||||
children,
|
||||
description,
|
||||
title,
|
||||
icon,
|
||||
children,
|
||||
description,
|
||||
}: {
|
||||
title: string;
|
||||
icon?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
description?: string;
|
||||
title: string;
|
||||
icon?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
description?: string;
|
||||
}) {
|
||||
return (
|
||||
<Card radius="md" shadow="sm" withBorder>
|
||||
<Group justify="apart" align="center" mb="xs">
|
||||
<Group align="center" gap="xs">
|
||||
{icon}
|
||||
<Text fw={700}>{title}</Text>
|
||||
</Group>
|
||||
{description && <Badge variant="light">{description}</Badge>}
|
||||
</Group>
|
||||
return (
|
||||
<Card radius="md" shadow="sm" withBorder>
|
||||
<Group justify="apart" align="center" mb="xs">
|
||||
<Group align="center" gap="xs">
|
||||
{icon}
|
||||
<Text fw={700}>{title}</Text>
|
||||
</Group>
|
||||
{description && <Badge variant="light">{description}</Badge>}
|
||||
</Group>
|
||||
|
||||
<Divider mb="sm" />
|
||||
<Stack gap="sm">{children}</Stack>
|
||||
</Card>
|
||||
);
|
||||
<Divider mb="sm" />
|
||||
<Stack gap="sm">{children}</Stack>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Main form component
|
||||
// =========================
|
||||
function FileInputWrapper({
|
||||
label,
|
||||
placeholder,
|
||||
accept,
|
||||
onChange,
|
||||
preview,
|
||||
name,
|
||||
description,
|
||||
}: {
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
accept?: string;
|
||||
onChange: (file: File | null) => void;
|
||||
preview?: string | null;
|
||||
name: string;
|
||||
description?: string;
|
||||
}) {
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
<Flex direction={"column"}>
|
||||
<Group justify="apart" align="center">
|
||||
<Text fw={500}>{label}</Text>
|
||||
</Group>
|
||||
{description && (
|
||||
<Text size="sm" c="dimmed" mt={4} style={{ lineHeight: 1.2 }}>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
export default function FormSurat() {
|
||||
const { data, mutate, isLoading } = useSWR("category-pelayanan-list", () =>
|
||||
apiFetch.api.pelayanan.category.get(),
|
||||
);
|
||||
<FileInput
|
||||
accept={accept}
|
||||
placeholder={placeholder}
|
||||
onChange={(f) => onChange(f)}
|
||||
leftSection={<IconUpload />}
|
||||
aria-label={label}
|
||||
name={name}
|
||||
/>
|
||||
|
||||
const listCategory = data?.data || [];
|
||||
|
||||
|
||||
useShallowEffect(() => {
|
||||
mutate();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container size="md" w={"100%"}>
|
||||
<Box>
|
||||
<Stack gap="lg">
|
||||
<Group justify="apart" align="center">
|
||||
<Group align="center">
|
||||
<IconBuildingCommunity size={28} />
|
||||
<div>
|
||||
<Text fw={800} size="xl">
|
||||
Surat Keterangan Tidak Mampu (SKTM)
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
Blangko resmi untuk pengajuan Surat Keterangan Tidak Mampu —
|
||||
digunakan untuk keperluan pendidikan, kesehatan, atau
|
||||
administrasi.
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
<Group>
|
||||
<Badge radius="sm">Form Length: 3 Sections</Badge>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
<form>
|
||||
<Stack gap="lg">
|
||||
{/* Header Section */}
|
||||
<FormSection
|
||||
title="Pemohon"
|
||||
icon={<IconUser size={16} />}
|
||||
description="Informasi identitas pemohon"
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Nama Lengkap"
|
||||
hint="Nama lengkap pemohon"
|
||||
/>
|
||||
}
|
||||
placeholder="Budi Setiawan"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Nomor Telephone"
|
||||
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
|
||||
/>
|
||||
}
|
||||
placeholder="08123456789"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={12}>
|
||||
<Select
|
||||
label={<FieldLabel label="Jenis Surat" hint="Jenis surat yang ingin diajukan" />}
|
||||
placeholder="Pilih jenis surat"
|
||||
data={listCategory.map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
}))}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
<FormSection
|
||||
title="Syarat Dokumen"
|
||||
description="Syarat dokumen yang diperlukan"
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Nama Lengkap"
|
||||
hint="Sesuai KTP"
|
||||
/>
|
||||
}
|
||||
placeholder="Nama lengkap"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="NIK"
|
||||
hint="16 digit, tanpa spasi"
|
||||
/>
|
||||
}
|
||||
placeholder="3201xxxxxxxxxxxx"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Tempat, Tanggal Lahir"
|
||||
hint="Contoh: Denpasar, 31-12-1990"
|
||||
/>
|
||||
}
|
||||
placeholder="Tempat, tanggal lahir"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<Select
|
||||
label={<FieldLabel label="Jenis Kelamin" />}
|
||||
placeholder="Pilih jenis kelamin"
|
||||
data={["Laki-laki", "Perempuan"]}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<Select
|
||||
label={<FieldLabel label="Agama" />}
|
||||
placeholder="Pilih agama"
|
||||
data={[
|
||||
"Islam",
|
||||
"Kristen",
|
||||
"Katolik",
|
||||
"Hindu",
|
||||
"Buddha",
|
||||
"Konghucu",
|
||||
"Lainnya",
|
||||
]}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<Select
|
||||
label={<FieldLabel label="Status Perkawinan" />}
|
||||
placeholder="Pilih status"
|
||||
data={[
|
||||
"Belum Kawin",
|
||||
"Kawin",
|
||||
"Cerai Hidup",
|
||||
"Cerai Mati",
|
||||
]}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Pekerjaan" />}
|
||||
placeholder="Pekerjaan"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={12}>
|
||||
<Textarea
|
||||
label={<FieldLabel label="Alamat Lengkap" />}
|
||||
placeholder="Alamat domisili"
|
||||
minRows={2}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={2}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="RT" />}
|
||||
placeholder="001"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={2}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="RW" />}
|
||||
placeholder="002"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={4}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Desa / Kelurahan" />}
|
||||
placeholder="Desa"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={4}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Kecamatan" />}
|
||||
placeholder="Kecamatan"
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={4}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Kabupaten / Kota" />}
|
||||
placeholder="Kabupaten / Kota"
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
{/* Keterangan Section */}
|
||||
<FormSection
|
||||
title="Keterangan"
|
||||
icon={<IconMapPin size={18} />}
|
||||
description="Isi pernyataan SKTM"
|
||||
>
|
||||
<Textarea
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Isi Surat"
|
||||
hint="Jelaskan kondisi ekonomi secara singkat"
|
||||
/>
|
||||
}
|
||||
placeholder="Pernyataan resmi bahwa yang bersangkutan benar-benar tergolong keluarga tidak mampu..."
|
||||
minRows={4}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Keperluan"
|
||||
hint="Contoh: Beasiswa pendidikan / Perawatan kesehatan"
|
||||
/>
|
||||
}
|
||||
placeholder="Keperluan surat"
|
||||
/>
|
||||
</FormSection>
|
||||
|
||||
{/* Actions */}
|
||||
<Group justify="right" mt="md">
|
||||
<Button variant="default" onClick={() => { }}>
|
||||
Reset
|
||||
</Button>
|
||||
<Button type="submit">Kirim / Simpan</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</form>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
{preview ? (
|
||||
<div>
|
||||
<Text size="xs" color="dimmed">
|
||||
Preview:
|
||||
</Text>
|
||||
{/* If preview is an image it will show; pdf preview might not render as image */}
|
||||
{/* Use <object> or <img> depending on file type — keep simple here */}
|
||||
<div style={{ marginTop: 6 }}>
|
||||
<img
|
||||
src={preview}
|
||||
alt={`${label} preview`}
|
||||
style={{ maxWidth: "200px", borderRadius: 4 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
620
src/pages/darmasaba/update_data_surat.tsx
Normal file
620
src/pages/darmasaba/update_data_surat.tsx
Normal file
@@ -0,0 +1,620 @@
|
||||
import FullScreenLoading from "@/components/FullScreenLoading";
|
||||
import ModalFile from "@/components/ModalFile";
|
||||
import notification from "@/components/notificationGlobal";
|
||||
import SuccessPengajuan from "@/components/SuccessPengajuanSurat";
|
||||
import apiFetch from "@/lib/apiFetch";
|
||||
import {
|
||||
ActionIcon,
|
||||
Alert,
|
||||
Anchor,
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
Container,
|
||||
Divider,
|
||||
FileInput,
|
||||
Flex,
|
||||
Grid,
|
||||
Group,
|
||||
Modal,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip
|
||||
} from "@mantine/core";
|
||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||
import {
|
||||
IconBuildingCommunity,
|
||||
IconInfoCircle,
|
||||
IconUpload
|
||||
} from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import React, { useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
type DataItem = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
type UpdateDataItem = {
|
||||
id: string;
|
||||
key: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
type FormSurat = {
|
||||
kategoriId: string;
|
||||
nama: string;
|
||||
phone: string;
|
||||
dataPelengkap: DataItem[];
|
||||
syaratDokumen: DataItem[];
|
||||
};
|
||||
|
||||
type FormUpdateSurat = {
|
||||
dataPelengkap: UpdateDataItem[];
|
||||
syaratDokumen: UpdateDataItem[];
|
||||
};
|
||||
|
||||
type DataPengajuan = {
|
||||
id: string;
|
||||
noPengajuan: string;
|
||||
category: string;
|
||||
status: "antrian" | "diproses" | "selesai" | "ditolak";
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
idSurat: string | undefined;
|
||||
}
|
||||
|
||||
export default function UpdateDataSurat() {
|
||||
const navigate = useNavigate();
|
||||
const { search } = useLocation();
|
||||
const query = new URLSearchParams(search);
|
||||
const noPengajuan = query.get("pengajuan");
|
||||
|
||||
|
||||
return (
|
||||
<Container size="md" w={"100%"}>
|
||||
<Box>
|
||||
<Stack gap="lg">
|
||||
<Group justify="space-between" align="center" mt={"lg"}>
|
||||
<Group align="center">
|
||||
<IconBuildingCommunity size={28} />
|
||||
<div>
|
||||
<Text fw={800} size="xl">
|
||||
Update Data Pengajuan Surat Administrasi
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
Formulir ini digunakan untuk memperbarui data pengajuan surat administrasi yang telah diajukan sebelumnya.
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
</Group>
|
||||
<Stack gap="lg" mb="lg">
|
||||
{
|
||||
!noPengajuan ? (
|
||||
<SearchData />
|
||||
)
|
||||
:
|
||||
<DataUpdate noPengajuan={noPengajuan} />
|
||||
}
|
||||
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
function FieldLabel({ label, hint }: { label: string; hint?: string }) {
|
||||
return (
|
||||
<Group justify="apart" gap="xs" align="center">
|
||||
<Text fw={600}>{label}</Text>
|
||||
{hint && (
|
||||
<Tooltip label={hint} withArrow>
|
||||
<ActionIcon size={24} variant="subtle">
|
||||
<IconInfoCircle size={16} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
function FormSection({
|
||||
title,
|
||||
icon,
|
||||
children,
|
||||
description,
|
||||
info,
|
||||
}: {
|
||||
title?: string;
|
||||
icon?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
description?: string;
|
||||
info?: string;
|
||||
}) {
|
||||
return (
|
||||
<Card radius="md" shadow="sm" withBorder>
|
||||
<Box mb="xs">
|
||||
<Group justify="apart" align="center">
|
||||
<Group align="center" gap="xs">
|
||||
{icon}
|
||||
{title && <Text fw={700}>{title}</Text>}
|
||||
</Group>
|
||||
{description && <Badge variant="light">{description}</Badge>}
|
||||
</Group>
|
||||
{info && <Text size="sm" c="dimmed">{info}</Text>}
|
||||
</Box>
|
||||
{
|
||||
title && <Divider mb="sm" />
|
||||
}
|
||||
<Stack gap="sm">{children}</Stack>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function FileInputWrapper({
|
||||
label,
|
||||
placeholder,
|
||||
accept,
|
||||
onChange,
|
||||
preview,
|
||||
name,
|
||||
description,
|
||||
linkView,
|
||||
disabled
|
||||
}: {
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
accept?: string;
|
||||
linkView?: string;
|
||||
onChange: (file: File | null) => void;
|
||||
preview?: string | null;
|
||||
name: string;
|
||||
description?: string;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
const [viewImg, setViewImg] = useState("");
|
||||
const [openedPreviewFile, setOpenedPreviewFile] = useState(false);
|
||||
|
||||
|
||||
useShallowEffect(() => {
|
||||
if (viewImg) {
|
||||
setOpenedPreviewFile(true);
|
||||
}
|
||||
}, [viewImg]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ModalFile
|
||||
open={openedPreviewFile && !_.isEmpty(viewImg)}
|
||||
onClose={() => {
|
||||
setOpenedPreviewFile(false);
|
||||
}}
|
||||
folder="syarat-dokumen"
|
||||
fileName={viewImg}
|
||||
/>
|
||||
|
||||
<Stack gap="xs">
|
||||
<Flex direction={"column"}>
|
||||
<Group justify="apart" align="center">
|
||||
<Text fw={500}>{label}</Text>
|
||||
</Group>
|
||||
{description && (
|
||||
<Text size="sm" c="dimmed" mt={4} style={{ lineHeight: 1.2 }}>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
{
|
||||
linkView && (
|
||||
<Anchor onClick={() => setViewImg(linkView)} size="sm">
|
||||
Lihat dokumen sebelumnya
|
||||
</Anchor>
|
||||
)
|
||||
}
|
||||
</Flex>
|
||||
|
||||
<FileInput
|
||||
accept={accept}
|
||||
placeholder={placeholder}
|
||||
onChange={(f) => onChange(f)}
|
||||
leftSection={<IconUpload />}
|
||||
aria-label={label}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
{preview ? (
|
||||
<div>
|
||||
<Text size="xs" color="dimmed">
|
||||
Preview:
|
||||
</Text>
|
||||
<div style={{ marginTop: 6 }}>
|
||||
<img
|
||||
src={preview}
|
||||
alt={`${label} preview`}
|
||||
style={{ maxWidth: "200px", borderRadius: 4 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Stack>
|
||||
</>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
function SearchData() {
|
||||
const [submitLoading, setSubmitLoading] = useState(false);
|
||||
const [searchPengajuan, setSearchPengajuan] = useState("");
|
||||
const [searchPengajuanPhone, setSearchPengajuanPhone] = useState("");
|
||||
const navigate = useNavigate();
|
||||
|
||||
async function handleSearch() {
|
||||
try {
|
||||
setSubmitLoading(true);
|
||||
if (searchPengajuan == "" || searchPengajuanPhone == "") {
|
||||
notification({
|
||||
title: "Peringatan",
|
||||
message: "Silakan isi nomor pengajuan atau nomor telephone",
|
||||
type: "warning"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await apiFetch.api.pelayanan["get-no-pengajuan"].post({
|
||||
phone: searchPengajuanPhone,
|
||||
noPengajuan: searchPengajuan
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
if (response.data?.success) {
|
||||
navigate(`/darmasaba/update-data-surat?pengajuan=${response.data.nomer}`);
|
||||
} else {
|
||||
notification({
|
||||
title: "Peringatan",
|
||||
message: response.data?.message || "Data pengajuan tidak valid",
|
||||
type: "warning"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
notification({
|
||||
title: "Error",
|
||||
message: "Pengajuan tidak ditemukan atau gagal memuat data",
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error searching:", error);
|
||||
notification({
|
||||
title: "Error",
|
||||
message: "Gagal mencari data pengajuan",
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FormSection
|
||||
title="Cari Pengajuan Surat"
|
||||
info="Masukkan nomor pengajuan dan nomor telepon yang digunakan saat pengajuan surat."
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={<FieldLabel label="Nomor Pengajuan" hint="Nomor pengajuan surat" />}
|
||||
placeholder="PS-2025-000123"
|
||||
onChange={(e) => { setSearchPengajuan(e.target.value) }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={6}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel
|
||||
label="Nomor Telephone"
|
||||
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
|
||||
/>
|
||||
}
|
||||
placeholder="08123456789"
|
||||
type="number"
|
||||
onChange={(e) => { setSearchPengajuanPhone(e.target.value) }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={12}>
|
||||
<Button fullWidth variant="light" color="blue" onClick={() => { handleSearch() }} loading={submitLoading}>
|
||||
Cari Pengajuan
|
||||
</Button>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</FormSection>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
|
||||
const [opened, { open, close }] = useDisclosure(false)
|
||||
const navigate = useNavigate()
|
||||
const [sukses, setSukses] = useState(false)
|
||||
const [submitLoading, setSubmitLoading] = useState(false)
|
||||
const [dataPelengkap, setDataPelengkap] = useState<DataItem[]>([])
|
||||
const [dataSyaratDokumen, setDataSyaratDokumen] = useState<DataItem[]>([])
|
||||
const [dataPengajuan, setDataPengajuan] = useState<DataPengajuan | {}>({})
|
||||
const [status, setStatus] = useState("")
|
||||
const [formSurat, setFormSurat] = useState<FormUpdateSurat>({
|
||||
dataPelengkap: [],
|
||||
syaratDokumen: [],
|
||||
});
|
||||
|
||||
async function fetchData() {
|
||||
try {
|
||||
const res = await apiFetch.api.pelayanan["detail-data"].post({ nomerPengajuan: noPengajuan });
|
||||
if (res.data && res.data.success === true) {
|
||||
setDataPelengkap(res.data.dataPelengkap || []);
|
||||
setDataSyaratDokumen(res.data.syaratDokumen || []);
|
||||
setDataPengajuan(res.data.pengajuan || {});
|
||||
|
||||
setStatus(res.data.pengajuan && 'status' in res.data.pengajuan ? res.data.pengajuan.status : "");
|
||||
} else {
|
||||
notification({
|
||||
title: "Error",
|
||||
message: res.data?.message || "Gagal memuat data",
|
||||
type: "error",
|
||||
});
|
||||
setDataPelengkap([]);
|
||||
setDataSyaratDokumen([]);
|
||||
setDataPengajuan({});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
}
|
||||
}
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
function upsertById<T extends { id: string }>(
|
||||
array: T[],
|
||||
item: T
|
||||
): T[] {
|
||||
const index = array.findIndex((v) => v.id === item.id)
|
||||
|
||||
// ➕ insert
|
||||
if (index === -1) {
|
||||
return [...array, item]
|
||||
}
|
||||
|
||||
// ✏️ update
|
||||
return array.map((v, i) => (i === index ? { ...v, ...item } : v))
|
||||
}
|
||||
|
||||
|
||||
function validationForm({
|
||||
kategori,
|
||||
value,
|
||||
}: {
|
||||
kategori: "dataPelengkap" | "syaratDokumen";
|
||||
value: UpdateDataItem;
|
||||
}) {
|
||||
setFormSurat((prev) => ({
|
||||
...prev,
|
||||
[kategori]: upsertById(prev[kategori], {
|
||||
id: value.id,
|
||||
key: value.key,
|
||||
value: value.value
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
function updateArrayByKey(
|
||||
list: UpdateDataItem[],
|
||||
id: string,
|
||||
value: any,
|
||||
): UpdateDataItem[] {
|
||||
return list.map((item) =>
|
||||
item.id === id ? { ...item, value } : item,
|
||||
);
|
||||
}
|
||||
|
||||
function onChecking() {
|
||||
if (formSurat.dataPelengkap.length == 0 && formSurat.syaratDokumen.length == 0)
|
||||
return notification({
|
||||
title: "Peringatan",
|
||||
message: "Tidak ada data yang diupdate",
|
||||
type: "warning",
|
||||
});
|
||||
const isFormKosong = Object.values(formSurat).some((value: UpdateDataItem[] | string) => {
|
||||
if (Array.isArray(value)) {
|
||||
return (
|
||||
value.some(
|
||||
(item) =>
|
||||
typeof item.value === "string" && item.value.trim() === "",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
return value.trim() === "";
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (isFormKosong) {
|
||||
return notification({
|
||||
title: "Gagal",
|
||||
message: "Silahkan lengkapi form surat",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
open()
|
||||
}
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
try {
|
||||
setSubmitLoading(true);
|
||||
// 🔥 CLONE state SEKALI
|
||||
let finalFormSurat = structuredClone(formSurat);
|
||||
|
||||
// 2️⃣ Upload satu per satu
|
||||
for (const itemUpload of finalFormSurat.syaratDokumen) {
|
||||
const updImg = await apiFetch.api.pengaduan.upload.post({
|
||||
file: itemUpload.value,
|
||||
folder: "syarat-dokumen",
|
||||
});
|
||||
|
||||
if (updImg.status === 200) {
|
||||
// 🔥 UPDATE OBJECT LOKAL (BUKAN STATE)
|
||||
finalFormSurat.syaratDokumen = updateArrayByKey(
|
||||
finalFormSurat.syaratDokumen,
|
||||
itemUpload.id,
|
||||
updImg.data?.filename || "",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 3️⃣ SET STATE SEKALI (optional, untuk UI)
|
||||
setFormSurat(finalFormSurat);
|
||||
|
||||
// 4️⃣ SUBMIT KE API
|
||||
const res = await apiFetch.api.pelayanan.update.post({
|
||||
id: dataPengajuan && ('id' in dataPengajuan) ? dataPengajuan.id : "",
|
||||
dataPelengkap: finalFormSurat.dataPelengkap,
|
||||
syaratDokumen: finalFormSurat.syaratDokumen,
|
||||
});
|
||||
|
||||
if (res.status === 200) {
|
||||
setSukses(true);
|
||||
} else {
|
||||
notification({
|
||||
title: "Gagal",
|
||||
message:
|
||||
"Pengajuan surat gagal dibuat, silahkan coba beberapa saat lagi",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification({
|
||||
title: "Gagal",
|
||||
message: "Server Error",
|
||||
type: "error",
|
||||
});
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<FullScreenLoading visible={submitLoading} />
|
||||
<Modal
|
||||
opened={opened}
|
||||
onClose={close}
|
||||
title={"Konfirmasi"}
|
||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Text>
|
||||
Apakah anda yakin ingin mengupdate pengajuan surat ini?
|
||||
</Text>
|
||||
<Group justify="center" grow>
|
||||
<Button variant="light" onClick={close}>
|
||||
Tidak
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
color="green"
|
||||
onClick={() => {
|
||||
onSubmit();
|
||||
close();
|
||||
}}
|
||||
>
|
||||
Ya
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
{
|
||||
sukses ?
|
||||
<SuccessPengajuan
|
||||
noPengajuan={noPengajuan}
|
||||
onClose={() => {
|
||||
navigate("/darmasaba/update-data-surat");
|
||||
}}
|
||||
category="update"
|
||||
/>
|
||||
:
|
||||
<>
|
||||
{
|
||||
(status != "ditolak" && status != "antrian")
|
||||
&& <Alert variant="light" color="yellow" radius="lg" title={`Data pengajuan surat ini tidak dapat diupdate karena berstatus ${status}.`} icon={<span style={{ fontSize: '1.2rem' }}>⚠</span>} />
|
||||
}
|
||||
<FormSection
|
||||
title="Data Pelengkap"
|
||||
description="Data pelengkap yang diperlukan"
|
||||
>
|
||||
<Grid>
|
||||
{dataPelengkap.map((item: any, index: number) => (
|
||||
<Grid.Col span={6} key={index}>
|
||||
<TextInput
|
||||
label={
|
||||
<FieldLabel label={item.name} hint={item.desc} />
|
||||
}
|
||||
placeholder={item.name}
|
||||
onChange={(e) =>
|
||||
validationForm({
|
||||
kategori: "dataPelengkap",
|
||||
value: { id: item.id, key: item.key, value: e.target.value },
|
||||
})
|
||||
}
|
||||
value={formSurat.dataPelengkap.find((n) => n.id === item.id)?.value ?? dataPelengkap.find((n: any) => n.key == item.key,)?.value}
|
||||
disabled={status != "ditolak" && status != "antrian"}
|
||||
/>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
<FormSection
|
||||
title="Syarat Dokumen"
|
||||
description="Syarat dokumen yang diperlukan"
|
||||
>
|
||||
<Grid>
|
||||
{dataSyaratDokumen.map((item: any, index: number) => (
|
||||
<Grid.Col span={6} key={index}>
|
||||
<FileInputWrapper
|
||||
label={item.desc}
|
||||
placeholder={"Upload file terbaru untuk mengupdate"}
|
||||
accept="image/*,application/pdf"
|
||||
linkView={item.value}
|
||||
onChange={(file) =>
|
||||
validationForm({
|
||||
kategori: "syaratDokumen",
|
||||
value: { id: item.id, key: item.key, value: file },
|
||||
})
|
||||
}
|
||||
name={item.name}
|
||||
disabled={status != "ditolak" && status != "antrian"}
|
||||
/>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
</FormSection>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Button onClick={() => { onChecking() }}>Kirim</Button>
|
||||
</Group>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Group,
|
||||
List,
|
||||
Modal,
|
||||
Spoiler,
|
||||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
@@ -432,41 +433,43 @@ function DetailDataHistori({ data }: { data: any }) {
|
||||
<Stack gap="md">
|
||||
<Flex align="center" justify="space-between">
|
||||
<Title order={4} c="gray.2">
|
||||
Histori Pengajuan Surat
|
||||
Riwayat Pengajuan Surat
|
||||
</Title>
|
||||
</Flex>
|
||||
<Divider my={0} />
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Tanggal</Table.Th>
|
||||
<Table.Th>Deskripsi</Table.Th>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>User</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{data?.map((item: any) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.createdAt.toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
})}
|
||||
</Table.Td>
|
||||
<Table.Td>{item.deskripsi}</Table.Td>
|
||||
<Table.Td>{item.status}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.nameUser ? item.nameUser : "-"}
|
||||
</Table.Td>
|
||||
<Spoiler maxHeight={200} showLabel="Show more" hideLabel="Hide" transitionDuration={1000}>
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Tanggal</Table.Th>
|
||||
<Table.Th>Deskripsi</Table.Th>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>User</Table.Th>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{data?.map((item: any) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.createdAt.toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
})}
|
||||
</Table.Td>
|
||||
<Table.Td>{item.deskripsi}</Table.Td>
|
||||
<Table.Td>{item.status}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.nameUser ? item.nameUser : "-"}
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Spoiler>
|
||||
</Stack>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
Grid,
|
||||
Group,
|
||||
Modal,
|
||||
Spoiler,
|
||||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
@@ -420,41 +421,43 @@ function DetailDataHistori({ data }: { data: any }) {
|
||||
<Stack gap="md">
|
||||
<Flex align="center" justify="space-between">
|
||||
<Title order={4} c="gray.2">
|
||||
Histori Pengaduan
|
||||
Riwayat Pengaduan
|
||||
</Title>
|
||||
</Flex>
|
||||
<Divider my={0} />
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Tanggal</Table.Th>
|
||||
<Table.Th>Deskripsi</Table.Th>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>User</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{data?.map((item: any) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.createdAt.toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
})}
|
||||
</Table.Td>
|
||||
<Table.Td>{item.deskripsi}</Table.Td>
|
||||
<Table.Td>{item.status}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.nameUser ? item.nameUser : "-"}
|
||||
</Table.Td>
|
||||
<Spoiler maxHeight={200} showLabel="Show more" hideLabel="Hide" transitionDuration={1000}>
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Tanggal</Table.Th>
|
||||
<Table.Th>Deskripsi</Table.Th>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>User</Table.Th>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{data?.map((item: any) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.createdAt.toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
})}
|
||||
</Table.Td>
|
||||
<Table.Td>{item.deskripsi}</Table.Td>
|
||||
<Table.Td>{item.status}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>
|
||||
{item.nameUser ? item.nameUser : "-"}
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Spoiler>
|
||||
</Stack>
|
||||
</Card>
|
||||
);
|
||||
|
||||
18
src/server/lib/slug_converter.ts
Normal file
18
src/server/lib/slug_converter.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export function toSlug(text: string): string {
|
||||
return encodeURIComponent(
|
||||
text
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
);
|
||||
}
|
||||
|
||||
export function fromSlug(slug: string): string {
|
||||
return decodeURIComponent(slug)
|
||||
.replace(/-/g, " ")
|
||||
.replace(/\b\w/g, c => c.toUpperCase());
|
||||
}
|
||||
|
||||
export function capitalizeWords(text: string): string {
|
||||
return text.replace(/\b\w/g, c => c.toUpperCase());
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { getLastUpdated } from "../lib/get-last-updated"
|
||||
import { generateNoPengajuanSurat } from "../lib/no-pengajuan-surat"
|
||||
import { isValidPhone, normalizePhoneNumber } from "../lib/normalizePhone"
|
||||
import { prisma } from "../lib/prisma"
|
||||
import { toSlug } from "../lib/slug_converter"
|
||||
|
||||
|
||||
const PelayananRoute = new Elysia({
|
||||
@@ -20,9 +21,21 @@ const PelayananRoute = new Elysia({
|
||||
},
|
||||
orderBy: {
|
||||
name: "asc"
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
syaratDokumen: true,
|
||||
dataPelengkap: true,
|
||||
}
|
||||
})
|
||||
return data
|
||||
|
||||
const dataFix = data.map(item => ({
|
||||
...item,
|
||||
link: `${process.env.BUN_PUBLIC_BASE_URL}/darmasaba/surat?jenis=${toSlug(item.name)}`
|
||||
}));
|
||||
|
||||
return dataFix
|
||||
}, {
|
||||
detail: {
|
||||
summary: "List Kategori Pelayanan Surat",
|
||||
@@ -105,12 +118,42 @@ const PelayananRoute = new Elysia({
|
||||
.get("/category/detail", async ({ query }) => {
|
||||
const { id } = query
|
||||
const data = await prisma.categoryPelayanan.findUnique({
|
||||
where:{
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
|
||||
return data
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataPelengkap: { key: string }[] = Array.isArray(data.dataPelengkap)
|
||||
? data.dataPelengkap.filter(
|
||||
(v): v is { key: string } =>
|
||||
typeof v === "object" &&
|
||||
v !== null &&
|
||||
"key" in v &&
|
||||
typeof (v as any).key === "string"
|
||||
)
|
||||
: [];
|
||||
|
||||
const syaratDokumen: { name: string }[] = Array.isArray(data.syaratDokumen)
|
||||
? data.syaratDokumen.filter(
|
||||
(v): v is { name: string } =>
|
||||
typeof v === "object" &&
|
||||
v !== null &&
|
||||
"name" in v &&
|
||||
typeof (v as any).name === "string"
|
||||
)
|
||||
: [];
|
||||
|
||||
|
||||
return {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
dataPelengkap,
|
||||
syaratDokumen,
|
||||
};
|
||||
}, {
|
||||
query: t.Object({
|
||||
id: t.String({ minLength: 1, error: "id harus diisi" }),
|
||||
@@ -184,8 +227,8 @@ const PelayananRoute = new Elysia({
|
||||
CategoryPelayanan: {
|
||||
select: {
|
||||
name: true,
|
||||
dataText: true,
|
||||
syaratDokumen: true,
|
||||
dataPelengkap: true
|
||||
}
|
||||
},
|
||||
Warga: {
|
||||
@@ -251,10 +294,11 @@ const PelayananRoute = new Elysia({
|
||||
const syaratDokumen = (data?.CategoryPelayanan?.syaratDokumen ?? []) as {
|
||||
name: string;
|
||||
desc: string;
|
||||
key: string;
|
||||
}[];
|
||||
|
||||
const dataSyaratFix = dataSyarat.map((item) => {
|
||||
const desc = syaratDokumen.find((v) => v.name == item.jenis)?.desc
|
||||
const desc = syaratDokumen.find((v) => v.key == item.jenis)?.desc
|
||||
return {
|
||||
id: item.id,
|
||||
jenis: desc,
|
||||
@@ -262,15 +306,35 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
|
||||
const dataTextFix = dataText.map((item) => {
|
||||
const desc = data?.CategoryPelayanan?.dataText.find((v) => v == item.jenis)
|
||||
return {
|
||||
id: item.id,
|
||||
jenis: item.jenis,
|
||||
value: item.value,
|
||||
}
|
||||
})
|
||||
const dataTextCategory = (data?.CategoryPelayanan?.dataPelengkap ?? []) as {
|
||||
name: string;
|
||||
desc: string;
|
||||
key: string;
|
||||
}[];
|
||||
|
||||
const refMap = new Map(
|
||||
dataTextCategory.map((v, i) => [
|
||||
v.key,
|
||||
{ ...v, order: i }
|
||||
])
|
||||
);
|
||||
|
||||
const dataTextFix = dataText
|
||||
.map((item) => {
|
||||
const ref = refMap.get(item.jenis);
|
||||
const nama = dataTextCategory.find((v) => v.key == item.jenis)?.name
|
||||
return {
|
||||
id: item.id,
|
||||
jenis: nama,
|
||||
value: item.value,
|
||||
order: ref?.order ?? Infinity,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map(({ order, ...rest }) => rest); // hapus order
|
||||
|
||||
|
||||
console.log(dataTextFix)
|
||||
const dataHistory = await prisma.historyPelayanan.findMany({
|
||||
where: {
|
||||
idPengajuanLayanan: data?.id,
|
||||
@@ -286,6 +350,9 @@ const PelayananRoute = new Elysia({
|
||||
name: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "desc"
|
||||
}
|
||||
})
|
||||
|
||||
@@ -336,9 +403,9 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
.post("/create", async ({ body, headers }) => {
|
||||
const { kategoriId, dataText, syaratDokumen } = body
|
||||
const namaWarga = headers['x-user'] || ""
|
||||
const noTelepon = headers['x-phone'] || ""
|
||||
const { kategoriId, dataPelengkap, syaratDokumen, nama, phone } = body
|
||||
// const namaWarga = headers['x-user'] || ""
|
||||
// const noTelepon = headers['x-phone'] || ""
|
||||
const noPengajuan = await generateNoPengajuanSurat()
|
||||
let idCategoryFix = kategoriId
|
||||
let idWargaFix = ""
|
||||
@@ -364,21 +431,21 @@ const PelayananRoute = new Elysia({
|
||||
|
||||
}
|
||||
|
||||
if (!isValidPhone(noTelepon)) {
|
||||
if (!isValidPhone(phone)) {
|
||||
return { success: false, message: 'nomor telepon tidak valid, harap masukkan nomor yang benar' }
|
||||
}
|
||||
|
||||
const nomorHP = normalizePhoneNumber({ phone: noTelepon })
|
||||
const nomorHP = normalizePhoneNumber({ phone: phone })
|
||||
const dataWarga = await prisma.warga.upsert({
|
||||
where: {
|
||||
phone: nomorHP
|
||||
},
|
||||
create: {
|
||||
name: namaWarga,
|
||||
name: nama,
|
||||
phone: nomorHP,
|
||||
},
|
||||
update: {
|
||||
name: namaWarga,
|
||||
name: nama,
|
||||
},
|
||||
select: {
|
||||
id: true
|
||||
@@ -409,16 +476,16 @@ const PelayananRoute = new Elysia({
|
||||
dataInsertSyaratDokumen.push({
|
||||
idPengajuanLayanan: pengaduan.id,
|
||||
idCategory: idCategoryFix,
|
||||
jenis: item.jenis,
|
||||
jenis: item.key,
|
||||
value: item.value,
|
||||
})
|
||||
}
|
||||
|
||||
for (const item of dataText) {
|
||||
for (const item of dataPelengkap) {
|
||||
dataInsertDataText.push({
|
||||
idPengajuanLayanan: pengaduan.id,
|
||||
idCategory: idCategoryFix,
|
||||
jenis: item.jenis,
|
||||
jenis: item.key,
|
||||
value: item.value,
|
||||
})
|
||||
}
|
||||
@@ -440,7 +507,7 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
|
||||
return { success: true, message: 'pengajuan layanan surat sudah dibuat dengan nomer ' + noPengajuan + ', nomer ini akan digunakan untuk mengakses pengajuan ini' }
|
||||
return { success: true, message: 'Pengajuan layanan surat sudah dibuat dengan nomer ' + noPengajuan + ', nomer ini akan digunakan untuk mengakses pengajuan ini', noPengajuan }
|
||||
}, {
|
||||
body: t.Object({
|
||||
kategoriId: t.String({
|
||||
@@ -448,21 +515,20 @@ const PelayananRoute = new Elysia({
|
||||
examples: ["skusaha"],
|
||||
error: "ID kategori harus diisi"
|
||||
}),
|
||||
// namaWarga: t.String({
|
||||
// description: "Nama warga",
|
||||
// examples: ["Budi Santoso"],
|
||||
// error: "Nama warga harus diisi"
|
||||
// }),
|
||||
nama: t.String({
|
||||
description: "Nama warga",
|
||||
examples: ["Budi Santoso"],
|
||||
error: "Nama warga harus diisi"
|
||||
}),
|
||||
phone: t.String({
|
||||
error: "Nomor telepon harus diisi",
|
||||
examples: ["08123456789", "+628123456789"],
|
||||
description: "Nomor telepon warga pelapor"
|
||||
}),
|
||||
|
||||
// noTelepon: t.String({
|
||||
// error: "Nomor telepon harus diisi",
|
||||
// examples: ["08123456789", "+628123456789"],
|
||||
// description: "Nomor telepon warga pelapor"
|
||||
// }),
|
||||
|
||||
dataText: t.Array(
|
||||
dataPelengkap: t.Array(
|
||||
t.Object({
|
||||
jenis: t.String({
|
||||
key: t.String({
|
||||
description: "Jenis field yang dibutuhkan oleh kategori pelayanan. Biasanya dinamis.",
|
||||
examples: ["nama", "jenis kelamin", "tempat tanggal lahir", "negara", "agama", "status perkawinan", "alamat", "pekerjaan", "jenis usaha", "alamat usaha"],
|
||||
error: "jenis harus diisi"
|
||||
@@ -477,25 +543,25 @@ 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" },
|
||||
{ key: "nama", value: "Budi Santoso" },
|
||||
{ key: "jenis kelamin", value: "Laki-laki" },
|
||||
{ key: "tempat tanggal lahir", value: "Denpasar, 28 Februari 1990" },
|
||||
{ key: "negara", value: "Indonesia" },
|
||||
{ key: "agama", value: "Islam" },
|
||||
{ key: "status perkawinan", value: "Belum menikah" },
|
||||
{ key: "alamat", value: "Jl. Mawar No. 10" },
|
||||
{ key: "pekerjaan", value: "Karyawan Swasta" },
|
||||
{ key: "jenis usaha", value: "usaha makanan" },
|
||||
{ key: "alamat usaha", value: "Jl. Melati No. 21" },
|
||||
]
|
||||
],
|
||||
error: "dataText harus berupa array"
|
||||
error: "Data Pelengkap harus berupa array"
|
||||
}
|
||||
),
|
||||
|
||||
syaratDokumen: t.Array(
|
||||
t.Object({
|
||||
jenis: t.String({
|
||||
key: t.String({
|
||||
description: "Jenis dokumen persyaratan yang diminta oleh kategori layanan.",
|
||||
examples: ["ktp", "kk", "surat_pengantar_rt"],
|
||||
error: "jenis harus diisi"
|
||||
@@ -510,19 +576,18 @@ const PelayananRoute = new Elysia({
|
||||
description: "Kumpulan dokumen yang wajib diupload sesuai persyaratan layanan.",
|
||||
examples: [
|
||||
[
|
||||
{ jenis: "pengantar kelian", value: "pengantar_kelurahan_budi.png" },
|
||||
{ jenis: "ktp/kk", value: "kk_budi.png" },
|
||||
{ jenis: "foto lokasi", value: "foto_lokasi_budi.png" }
|
||||
{ key: "pengantar kelian", value: "pengantar_kelurahan_budi.png" },
|
||||
{ key: "ktp/kk", value: "kk_budi.png" },
|
||||
{ key: "foto lokasi", value: "foto_lokasi_budi.png" }
|
||||
]
|
||||
],
|
||||
error: "syaratDokumen harus berupa array"
|
||||
error: "Syarat Dokumen harus berupa array"
|
||||
}
|
||||
),
|
||||
}),
|
||||
detail: {
|
||||
summary: "Buat Pengajuan Pelayanan Surat",
|
||||
description: `tool untuk membuat pengajuan pelayanan surat dengan syarat dokumen serta data text sesuai kategori pelayanan surat yang dipilih`,
|
||||
tags: ["mcp"]
|
||||
}
|
||||
})
|
||||
.post("/detail-data", async ({ body }) => {
|
||||
@@ -540,7 +605,7 @@ const PelayananRoute = new Elysia({
|
||||
CategoryPelayanan: {
|
||||
select: {
|
||||
name: true,
|
||||
dataText: true,
|
||||
dataPelengkap: true,
|
||||
syaratDokumen: true,
|
||||
}
|
||||
},
|
||||
@@ -560,7 +625,15 @@ const PelayananRoute = new Elysia({
|
||||
})
|
||||
|
||||
if (!data) {
|
||||
return { success: false, message: "Data tidak ditemukan" }
|
||||
return {
|
||||
success: false,
|
||||
message: "Data tidak ditemukan",
|
||||
pengajuan: {},
|
||||
history: [],
|
||||
warga: {},
|
||||
syaratDokumen: [],
|
||||
dataPelengkap: [],
|
||||
}
|
||||
}
|
||||
|
||||
const dataSurat = await prisma.suratPelayanan.findFirst({
|
||||
@@ -586,7 +659,7 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
|
||||
const dataText = await prisma.dataTextPelayanan.findMany({
|
||||
const dataPelengkap = await prisma.dataTextPelayanan.findMany({
|
||||
where: {
|
||||
idPengajuanLayanan: data?.id,
|
||||
isActive: true
|
||||
@@ -600,25 +673,50 @@ const PelayananRoute = new Elysia({
|
||||
const syaratDokumen = (data?.CategoryPelayanan?.syaratDokumen ?? []) as {
|
||||
name: string;
|
||||
desc: string;
|
||||
key: string;
|
||||
}[];
|
||||
|
||||
const dataSyaratFix = dataSyarat.map((item) => {
|
||||
// const desc = syaratDokumen.find((v) => v.name == item.jenis)?.desc
|
||||
const desc = syaratDokumen.find((v) => v.key == item.jenis)?.desc
|
||||
const name = syaratDokumen.find((v) => v.key == item.jenis)?.name
|
||||
return {
|
||||
id: item.id,
|
||||
jenis: item.jenis,
|
||||
key: item.jenis,
|
||||
value: item.value,
|
||||
name: name ?? '',
|
||||
desc: desc ?? ''
|
||||
}
|
||||
})
|
||||
|
||||
const dataTextFix = dataText.map((item) => {
|
||||
// const desc = data?.CategoryPelayanan?.dataText.find((v) => v == item.jenis)
|
||||
return {
|
||||
id: item.id,
|
||||
jenis: item.jenis,
|
||||
value: item.value,
|
||||
}
|
||||
})
|
||||
const dataPelengkapList = (data?.CategoryPelayanan?.dataPelengkap ?? []) as {
|
||||
name: string;
|
||||
desc: string;
|
||||
key: string;
|
||||
}[];
|
||||
|
||||
const refMap = new Map(
|
||||
dataPelengkapList.map((v, i) => [
|
||||
v.key,
|
||||
{ ...v, order: i }
|
||||
])
|
||||
);
|
||||
|
||||
const dataTextFix = dataPelengkap
|
||||
.map((item) => {
|
||||
const ref = refMap.get(item.jenis);
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
key: item.jenis,
|
||||
value: item.value,
|
||||
desc: ref?.desc ?? "",
|
||||
name: ref?.name ?? "",
|
||||
order: ref?.order ?? Infinity,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map(({ order, ...rest }) => rest); // hapus order
|
||||
|
||||
|
||||
const dataHistory = await prisma.historyPelayanan.findMany({
|
||||
where: {
|
||||
@@ -667,15 +765,15 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
|
||||
const datafix = {
|
||||
success: true,
|
||||
message: 'sukses',
|
||||
pengajuan: dataPengajuan,
|
||||
history: dataHistoryFix,
|
||||
warga: warga,
|
||||
syaratDokumen: dataSyaratFix,
|
||||
dataText: dataTextFix,
|
||||
dataPelengkap: dataTextFix,
|
||||
}
|
||||
|
||||
console.log('detail data syarat==', dataSyaratFix)
|
||||
|
||||
return datafix
|
||||
|
||||
}, {
|
||||
@@ -752,51 +850,34 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
.post("/update", async ({ body }) => {
|
||||
const { nomerPengajuan, syaratDokumen, dataText } = body
|
||||
const { id, syaratDokumen, dataPelengkap } = body
|
||||
let dataUpdate = []
|
||||
console.log(body)
|
||||
|
||||
const pengajuan = await prisma.pelayananAjuan.findFirst({
|
||||
const pengajuan = await prisma.pelayananAjuan.findUnique({
|
||||
where: {
|
||||
noPengajuan: nomerPengajuan,
|
||||
id
|
||||
}
|
||||
})
|
||||
|
||||
if (!pengajuan) {
|
||||
console.log("data pengajuan surat tidak ditemukan")
|
||||
return { success: false, message: 'data pengajuan surat tidak ditemukan' }
|
||||
}
|
||||
|
||||
|
||||
if (pengajuan.status != "ditolak" && pengajuan.status != "antrian") {
|
||||
console.log("pengajuan surat tidak dapat diupdate karena status " + pengajuan.status)
|
||||
return { success: false, message: 'pengajuan surat tidak dapat diupdate karena status ' + pengajuan.status }
|
||||
}
|
||||
|
||||
if (dataText && dataText.length > 0) {
|
||||
console.log("dataText")
|
||||
for (const item of dataText) {
|
||||
dataUpdate.push(item.jenis)
|
||||
const hasil = await prisma.dataTextPelayanan.findFirst({
|
||||
where: {
|
||||
idPengajuanLayanan: pengajuan.id,
|
||||
jenis: item.jenis,
|
||||
}
|
||||
})
|
||||
if (dataPelengkap && dataPelengkap.length > 0) {
|
||||
for (const item of dataPelengkap) {
|
||||
dataUpdate.push(item.key)
|
||||
|
||||
|
||||
const upd = await prisma.dataTextPelayanan.upsert({
|
||||
const upd = await prisma.dataTextPelayanan.update({
|
||||
where: {
|
||||
id: hasil?.id
|
||||
id: item.id
|
||||
},
|
||||
update: {
|
||||
data: {
|
||||
value: item.value,
|
||||
},
|
||||
create: {
|
||||
value: item.value,
|
||||
jenis: item.jenis,
|
||||
idPengajuanLayanan: pengajuan.id,
|
||||
idCategory: pengajuan.idCategory,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -818,38 +899,16 @@ const PelayananRoute = new Elysia({
|
||||
|
||||
|
||||
if (syaratDokumen && syaratDokumen.length > 0) {
|
||||
console.log("syaratDokumen")
|
||||
for (const item of syaratDokumen) {
|
||||
const pilih = syarat?.find((cat) => cat.desc.toLowerCase() == item.jenis.toLowerCase() || cat.name.toLowerCase() == item.jenis.toLowerCase())?.name;
|
||||
console.log(syarat, pilih)
|
||||
dataUpdate.push(pilih)
|
||||
|
||||
const hasil = await prisma.syaratDokumenPelayanan.findFirst({
|
||||
dataUpdate.push(item.key)
|
||||
const upd = await prisma.syaratDokumenPelayanan.update({
|
||||
where: {
|
||||
idPengajuanLayanan: pengajuan.id,
|
||||
jenis: pilih,
|
||||
id: item.id
|
||||
},
|
||||
data: {
|
||||
value: item.value,
|
||||
}
|
||||
})
|
||||
console.log(hasil, item)
|
||||
|
||||
if (hasil && hasil.id) {
|
||||
const upd = await prisma.syaratDokumenPelayanan.upsert({
|
||||
where: {
|
||||
id: hasil.id
|
||||
},
|
||||
update: {
|
||||
value: item.value,
|
||||
},
|
||||
create: {
|
||||
value: item.value,
|
||||
jenis: hasil.jenis,
|
||||
idPengajuanLayanan: pengajuan.id,
|
||||
idCategory: pengajuan.idCategory,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return { success: false, message: 'dokumen tidak dapat diupload' }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,22 +933,25 @@ const PelayananRoute = new Elysia({
|
||||
}
|
||||
})
|
||||
|
||||
console.log("pengajuan surat sudah diperbarui")
|
||||
|
||||
return { success: true, message: 'pengajuan surat sudah diperbarui' }
|
||||
|
||||
}, {
|
||||
body: t.Object({
|
||||
nomerPengajuan: t.String({
|
||||
error: "nomer pengajuan harus diisi",
|
||||
description: "Nomer pengajuan yang ingin diupdate"
|
||||
id: t.String({
|
||||
error: "id harus diisi",
|
||||
description: "ID yang ingin diupdate"
|
||||
}),
|
||||
dataText: t.Optional(t.Array(
|
||||
dataPelengkap: t.Optional(t.Array(
|
||||
t.Object({
|
||||
jenis: t.String({
|
||||
description: "Jenis field yang dibutuhkan oleh kategori pelayanan. Biasanya dinamis.",
|
||||
id: t.String({
|
||||
description: "ID Data Pelengkap.",
|
||||
error: "id harus diisi"
|
||||
}),
|
||||
key: t.String({
|
||||
description: "Key field yang dibutuhkan oleh kategori pelayanan. Biasanya dinamis.",
|
||||
examples: ["nama", "jenis kelamin", "tempat tanggal lahir", "negara", "agama", "status perkawinan", "alamat", "pekerjaan", "jenis usaha", "alamat usaha"],
|
||||
error: "jenis harus diisi"
|
||||
error: "key harus diisi"
|
||||
}),
|
||||
value: t.String({
|
||||
description: "Isi atau nilai dari jenis field terkait.",
|
||||
@@ -901,26 +963,30 @@ 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" },
|
||||
{ id: "1", key: "nama", value: "Budi Santoso" },
|
||||
{ id: "2", key: "jenis kelamin", value: "Laki-laki" },
|
||||
{ id: "3", key: "tempat tanggal lahir", value: "Denpasar, 28 Februari 1990" },
|
||||
{ id: "4", key: "negara", value: "Indonesia" },
|
||||
{ id: "5", key: "agama", value: "Islam" },
|
||||
{ id: "6", key: "status perkawinan", value: "Belum menikah" },
|
||||
{ id: "7", key: "alamat", value: "Jl. Mawar No. 10" },
|
||||
{ id: "8", key: "pekerjaan", value: "Karyawan Swasta" },
|
||||
{ id: "9", key: "jenis usaha", value: "usaha makanan" },
|
||||
{ id: "10", key: "alamat usaha", value: "Jl. Melati No. 21" },
|
||||
]
|
||||
],
|
||||
}
|
||||
)),
|
||||
syaratDokumen: t.Optional(t.Array(
|
||||
t.Object({
|
||||
jenis: t.String({
|
||||
description: "Jenis dokumen persyaratan yang diminta oleh kategori layanan.",
|
||||
id: t.String({
|
||||
description: "ID syarat dokumen",
|
||||
error: "id harus diisi"
|
||||
}),
|
||||
key: t.String({
|
||||
description: "Key dokumen persyaratan yang diminta oleh kategori layanan.",
|
||||
examples: ["ktp", "kk", "surat_pengantar_rt"],
|
||||
error: "jenis harus diisi"
|
||||
error: "key harus diisi"
|
||||
}),
|
||||
value: t.String({
|
||||
description: "Nama file atau identifier file dokumen yang diupload.",
|
||||
@@ -932,9 +998,9 @@ const PelayananRoute = new Elysia({
|
||||
description: "Kumpulan dokumen yang wajib diupload sesuai persyaratan layanan.",
|
||||
examples: [
|
||||
[
|
||||
{ jenis: "pengantar kelian", value: "pengantar_kelurahan_budi.png" },
|
||||
{ jenis: "ktp/kk", value: "kk_budi.png" },
|
||||
{ jenis: "foto lokasi", value: "foto_lokasi_budi.png" }
|
||||
{ id: "1", key: "pengantar kelian", value: "pengantar_kelurahan_budi.png" },
|
||||
{ id: "2", key: "ktp/kk", value: "kk_budi.png" },
|
||||
{ id: "3", key: "foto lokasi", value: "foto_lokasi_budi.png" }
|
||||
]
|
||||
],
|
||||
}
|
||||
@@ -943,7 +1009,6 @@ const PelayananRoute = new Elysia({
|
||||
detail: {
|
||||
summary: "Update Data Pengajuan Pelayanan Surat",
|
||||
description: `tool untuk update data pengajuan pelayanan surat`,
|
||||
tags: ["mcp"]
|
||||
}
|
||||
})
|
||||
.get("/list", async ({ query }) => {
|
||||
@@ -1090,5 +1155,47 @@ const PelayananRoute = new Elysia({
|
||||
description: `tool untuk mendapatkan jumlah pengajuan pelayanan surat warga`,
|
||||
}
|
||||
})
|
||||
.post("/get-no-pengajuan", async ({ body }) => {
|
||||
const { phone, noPengajuan } = body;
|
||||
|
||||
if (!isValidPhone(phone)) {
|
||||
return { success: false, message: 'nomor telepon tidak valid, harap masukkan nomor yang benar' }
|
||||
}
|
||||
|
||||
const nomorHP = normalizePhoneNumber({ phone: phone })
|
||||
const data = await prisma.pelayananAjuan.findMany({
|
||||
where: {
|
||||
noPengajuan: noPengajuan,
|
||||
Warga: {
|
||||
phone: nomorHP
|
||||
}
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
noPengajuan: true,
|
||||
status: true,
|
||||
createdAt: true,
|
||||
}
|
||||
});
|
||||
|
||||
if (data.length == 0) {
|
||||
return { success: false, message: 'Data pengajuan tidak ditemukan' };
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
nomer: noPengajuan
|
||||
};
|
||||
|
||||
}, {
|
||||
body: t.Object({
|
||||
phone: t.String({ minLength: 1, error: "Nomor telepon harus diisi" }),
|
||||
noPengajuan: t.String({ minLength: 1, error: "Nomor pengajuan harus diisi" }),
|
||||
}),
|
||||
detail: {
|
||||
summary: "Cek Nomor Pengajuan Surat",
|
||||
description: `tool untuk memeriksa apakah nomor pengajuan surat valid dan terkait dengan nomor telepon warga. Jika valid, mengembalikan nomor pengajuan.`,
|
||||
}
|
||||
})
|
||||
|
||||
export default PelayananRoute
|
||||
|
||||
@@ -436,6 +436,9 @@ const PengaduanRoute = new Elysia({
|
||||
name: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "desc"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user