upd : update pengajuan surat

deskripsi:
- update type form pada tambah dan update pengajuan surat
- tampilan klo tidak ada data yg dicari pada update pengajuan surat
- update seeder category pengajuan surat

No Issues
This commit is contained in:
2025-12-24 17:29:25 +08:00
parent bab832b87f
commit c074e2bc0a
9 changed files with 536 additions and 233 deletions

View File

@@ -22,13 +22,19 @@ import {
TextInput,
Tooltip,
} from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import {
IconBuildingCommunity,
IconCategory,
IconFiles,
IconInfoCircle,
IconUpload,
IconUser,
IconNotes,
IconPhone,
IconUpload
} from "@tabler/icons-react";
import dayjs from "dayjs";
import "dayjs/locale/id";
import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import useSWR from "swr";
@@ -310,44 +316,15 @@ export default function FormSurat() {
</div>
</Group>
<Group>
<Badge radius="sm">Form Length: 3 Sections</Badge>
<Badge radius="sm">Form Length: 4 Sections</Badge>
</Group>
</Group>
<Stack gap="lg">
{/* Header Section */}
<FormSection
title="Pemohon"
icon={<IconUser size={16} />}
description="Informasi identitas pemohon"
title="Jenis Surat Pengajuan"
icon={<IconCategory size={16} />}
>
<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={
@@ -371,32 +348,110 @@ export default function FormSurat() {
</Grid>
</FormSection>
{/* Kontak Section */}
<FormSection
title="Kontak"
icon={<IconPhone size={16} />}
description="Informasi kontak yg dapat dihubungi"
>
<Grid>
<Grid.Col span={6}>
<TextInput
label={<FieldLabel label="Nama" hint="Nama kontak" />}
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>
</FormSection>
{jenisSuratFix.id != "" && dataSurat && dataSurat.dataPelengkap && (
<>
<FormSection
title="Data Pelengkap"
description="Data pelengkap yang diperlukan"
title="Data Yang Diperlukan"
description="Data yang diperlukan untuk mengajukan surat"
icon={<IconNotes size={16} />}
>
<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
}
/>
{
item.type == "enum"
?
<Select
label={
<FieldLabel label={item.name} hint={item.desc} />
}
data={item.options ?? []}
placeholder={item.name}
onChange={(e) => {
validationForm({
key: "dataPelengkap",
value: { key: item.key, value: e }
})
}}
value={formSurat.dataPelengkap.find((n: any) => n.key == item.key)?.value}
/>
: item.type == "date"
?
<DateInput
locale="id"
valueFormat="DD MMMM YYYY"
label={
<FieldLabel label={item.name} hint={item.desc} />
}
placeholder={item.name}
onChange={(e) => {
const formatted = e
? dayjs(e).locale("id").format("DD MMMM YYYY")
: "";
validationForm({
key: "dataPelengkap",
value: { key: item.key, value: formatted },
})
}}
/>
:
<TextInput
type={item.type}
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>
@@ -405,6 +460,7 @@ export default function FormSurat() {
<FormSection
title="Syarat Dokumen"
description="Syarat dokumen yang diperlukan"
icon={<IconFiles size={16} />}
>
<Grid>
{dataSurat.syaratDokumen.map((item: any, index: number) => (

View File

@@ -1,8 +1,10 @@
import FullScreenLoading from "@/components/FullScreenLoading";
import ModalFile from "@/components/ModalFile";
import { DataNotFound } from "@/components/NotFoundPengajuanSurat";
import notification from "@/components/notificationGlobal";
import SuccessPengajuan from "@/components/SuccessPengajuanSurat";
import apiFetch from "@/lib/apiFetch";
import { parseTanggalID } from "@/server/lib/stringToDate";
import {
ActionIcon,
Alert,
@@ -18,17 +20,23 @@ import {
Grid,
Group,
Modal,
Select,
Stack,
Text,
TextInput,
Tooltip
} from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import {
IconBuildingCommunity,
IconFiles,
IconInfoCircle,
IconNotes,
IconUpload
} from "@tabler/icons-react";
import dayjs from "dayjs";
import "dayjs/locale/id";
import _ from "lodash";
import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
@@ -72,34 +80,41 @@ export default function UpdateDataSurat() {
const { search } = useLocation();
const query = new URLSearchParams(search);
const noPengajuan = query.get("pengajuan");
const [found, setFound] = useState(true);
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>
{
found &&
<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>
</Group>
}
<Stack gap="lg" mb="lg">
{
!noPengajuan ? (
<SearchData />
)
:
<DataUpdate noPengajuan={noPengajuan} />
found ? (
<DataUpdate noPengajuan={noPengajuan} onValidate={(e) => { setFound(e) }} />
) : (
<DataNotFound backTo={() => navigate("/darmasaba/update-data-surat")} />
)
}
</Stack>
</Stack>
</Box>
@@ -338,7 +353,7 @@ function SearchData() {
}
function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
function DataUpdate({ noPengajuan, onValidate }: { noPengajuan: string, onValidate: (e: boolean) => void }) {
const [opened, { open, close }] = useDisclosure(false)
const navigate = useNavigate()
const [sukses, setSukses] = useState(false)
@@ -356,20 +371,23 @@ function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
try {
const res = await apiFetch.api.pelayanan["detail-data"].post({ nomerPengajuan: noPengajuan });
if (res.data && res.data.success === true) {
onValidate(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",
});
// notification({
// title: "Error",
// message: res.data?.message || "Gagal memuat data",
// type: "error",
// });
onValidate(false)
setDataPelengkap([]);
setDataSyaratDokumen([]);
setDataPengajuan({});
}
} catch (error) {
console.error('Error fetching data:', error);
@@ -559,26 +577,73 @@ function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
&& <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"
title="Data Yang Diperlukan"
description="Data yang diperlukan"
icon={<IconNotes size={16} />}
>
<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"}
/>
{
item.type == "enum"
?
<Select
label={
<FieldLabel label={item.name} hint={item.desc} />
}
data={item.options ?? []}
placeholder={item.name}
onChange={(e) => {
validationForm({
kategori: "dataPelengkap",
value: { id: item.id, key: item.key, value: e }
})
}}
value={formSurat.dataPelengkap.find((n: any) => n.key == item.key)?.value || dataPelengkap.find((n: any) => n.key == item.key)?.value}
/>
: item.type == "date"
?
<DateInput
locale="id"
valueFormat="DD MMMM YYYY"
label={
<FieldLabel label={item.name} hint={item.desc} />
}
placeholder={item.name}
onChange={(e) => {
const formatted = e
? dayjs(e).locale("id").format("DD MMMM YYYY")
: "";
validationForm({
kategori: "dataPelengkap",
value: { id: item.id, key: item.key, value: formatted },
})
}}
value={
formSurat.dataPelengkap.find((n: any) => n.key === item.key)?.value ?
parseTanggalID(
formSurat.dataPelengkap.find((n: any) => n.key === item.key)?.value
) :
parseTanggalID(
item.value
)
}
/>
: <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>
@@ -587,6 +652,7 @@ function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
<FormSection
title="Syarat Dokumen"
description="Syarat dokumen yang diperlukan"
icon={<IconFiles size={16} />}
>
<Grid>
{dataSyaratDokumen.map((item: any, index: number) => (
@@ -611,7 +677,7 @@ function DataUpdate({ noPengajuan }: { noPengajuan: string }) {
</FormSection>
<Group justify="right" mt="md">
<Button onClick={() => { onChecking() }}>Kirim</Button>
<Button onClick={() => { onChecking() }} disabled={status != "ditolak" && status != "antrian"}>Kirim</Button>
</Group>
</>
}