Merge pull request 'amalia/22-des-25' (#93) from amalia/22-des-25 into main

Reviewed-on: http://wibugit.wibudev.com/wibu/jenna-mcp/pulls/93
This commit is contained in:
2025-12-22 17:39:31 +08:00
5 changed files with 469 additions and 252 deletions

View File

@@ -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,
@@ -233,15 +232,15 @@ export default function KategoriPelayananSurat({
}
/>
</Input.Wrapper>
<TagsInput
{/* <TagsInput
label="Data Pelengkap"
placeholder="Tambah data pelengkap"
splitChars={[","]}
value={dataChoose.dataText}
value={dataChoose.dataPelengkap}
onChange={(value) =>
setDataChoose({ ...dataChoose, dataText: value })
setDataChoose({ ...dataChoose, dataPelengkap: value })
}
/>
/> */}
<Flex direction={"column"} gap={"md"}>
<Group>
<Text size="sm" c={"white"}>
@@ -295,6 +294,7 @@ export default function KategoriPelayananSurat({
value={v.name}
onChange={(e) =>
handleEditSyarat(i, {
key: v.key,
name: e.target.value,
desc: v.desc,
})
@@ -308,6 +308,7 @@ export default function KategoriPelayananSurat({
value={v.desc}
onChange={(e) =>
handleEditSyarat(i, {
key: v.key,
name: v.name,
desc: e.target.value,
})
@@ -347,7 +348,7 @@ export default function KategoriPelayananSurat({
}
/>
</Input.Wrapper>
<TagsInput
{/* <TagsInput
label="Data Pelengkap"
placeholder="Tambah data pelengkap"
splitChars={[","]}
@@ -355,7 +356,7 @@ export default function KategoriPelayananSurat({
onChange={(value) =>
setDataTambah({ ...dataTambah, dataText: value })
}
/>
/> */}
<Flex direction={"column"} gap={"md"}>
<Group>
<Text size="sm" c={"white"}>
@@ -372,7 +373,7 @@ export default function KategoriPelayananSurat({
...dataTambah,
syaratDokumen: [
...dataTambah.syaratDokumen,
{ name: "", desc: "" },
{ key: "", name: "", desc: "" },
],
});
}}
@@ -524,8 +525,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>

View File

@@ -4,11 +4,13 @@ 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">
@@ -17,11 +19,11 @@ export default function SuccessPengajuan({
<IconCheck size={56} color="green" />
<Title order={3} ta="center">
Pengajuan Berhasil Dibuat
{category == 'create' ? 'Pengajuan Berhasil Dibuat' : 'Pengajuan Berhasil Diupdate'}
</Title>
<Text ta="center" size="sm" c="dimmed">
Pengajuan layanan surat sudah dibuat dengan nomor:
{category == 'create' ? 'Pengajuan layanan surat sudah dibuat dengan nomor:' : 'Pengajuan layanan surat sudah diupdate dengan nomor:'}
</Text>
<Badge size="xl" variant="light" color="green">

View File

@@ -15,13 +15,14 @@ import {
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,
@@ -46,6 +47,7 @@ type FormSurat = {
};
export default function FormSurat() {
const [opened, { open, close }] = useDisclosure(false);
const [noPengajuan, setNoPengajuan] = useState("");
const [submitLoading, setSubmitLoading] = useState(false);
const navigate = useNavigate();
@@ -141,7 +143,7 @@ export default function FormSurat() {
}
}, [jenisSuratFix.id]);
async function onSubmit() {
function onChecking() {
const isFormKosong = Object.values(formSurat).some((value) => {
if (Array.isArray(value)) {
return (
@@ -166,8 +168,12 @@ export default function FormSurat() {
message: "Silahkan lengkapi form surat",
type: "error",
});
} else {
open();
}
}
async function onSubmit() {
try {
setSubmitLoading(true);
// 🔥 CLONE state SEKALI
@@ -197,11 +203,7 @@ export default function FormSurat() {
const res = await apiFetch.api.pelayanan.create.post(finalFormSurat);
if (res.status === 200) {
notification({
title: "Berhasil",
message: res.data?.message || "Pengajuan surat berhasil dibuat",
type: "success",
});
setNoPengajuan(res.data?.noPengajuan || "");
} else {
notification({
title: "Gagal",
@@ -252,161 +254,192 @@ export default function FormSurat() {
}
return (
<Container size="md" w={"100%"}>
<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 != "" && (
{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>
)
:
<Box>
<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>
<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 span={6}>
<TextInput
label={
<FieldLabel
label="Nomor Telephone"
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
/>
</Grid.Col>
))}
</Grid>
</FormSection>
}
placeholder="08123456789"
value={formSurat.phone}
onChange={(e) =>
validationForm({ key: "phone", value: e.target.value })
}
/>
</Grid.Col>
<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 span={12}>
<Select
label={
<FieldLabel
label="Jenis Surat"
hint="Jenis surat yang ingin diajukan"
/>
</Grid.Col>
))}
</Grid>
</FormSection>
}
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>
{/* Actions */}
<Group justify="right" mt="md">
<Button variant="default" onClick={() => {}}>
{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={onSubmit}>Kirim</Button>
</Group>
</>
)}
</Button> */}
<Button onClick={onChecking}>Kirim</Button>
</Group>
</>
)}
</Stack>
</Stack>
</Stack>
</Box>
</Box>
}
</Container>
);
}

View File

@@ -1,5 +1,7 @@
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,
@@ -15,12 +17,13 @@ import {
Flex,
Grid,
Group,
Modal,
Stack,
Text,
TextInput,
Tooltip
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import {
IconBuildingCommunity,
IconInfoCircle,
@@ -336,6 +339,10 @@ function SearchData() {
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 | {}>({})
@@ -406,69 +413,208 @@ function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
}));
}
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>
{
(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>} />
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>
</>
}
<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={() => console.log('Submit clicked')}>Kirim</Button>
</Group>
</>
)
}

View File

@@ -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",
@@ -299,14 +312,26 @@ const PelayananRoute = new Elysia({
key: string;
}[];
const dataTextFix = dataText.map((item) => {
const nama = dataTextCategory.find((v) => v.key == item.jenis)?.name
return {
id: item.id,
jenis: nama,
value: item.value,
}
})
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
const dataHistory = await prisma.historyPelayanan.findMany({
where: {
@@ -477,7 +502,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({
@@ -664,18 +689,29 @@ const PelayananRoute = new Elysia({
key: string;
}[];
const dataTextFix = dataPelengkap.map((item) => {
const ini = dataPelengkapList.find((v) => v.key == item.jenis)
const desc = ini?.desc
const name = ini?.name
return {
id: item.id,
key: item.jenis,
value: item.value,
desc: desc ?? '',
name: name ?? ''
}
})
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: {
@@ -733,7 +769,6 @@ const PelayananRoute = new Elysia({
dataPelengkap: dataTextFix,
}
return datafix
}, {