pelayanan surat

deskripsi:
- update validasi form tambah pengajuan layanan surat
- update validasi form update pengajuan layanan surat

No Issues
This commit is contained in:
2026-01-07 12:02:27 +08:00
parent 411f61ec15
commit 8f33ec2ffa
2 changed files with 106 additions and 15 deletions

View File

@@ -52,7 +52,10 @@ type FormSurat = {
syaratDokumen: DataItem[]; syaratDokumen: DataItem[];
}; };
type ErrorState = Record<string, string | null>;
export default function FormSurat() { export default function FormSurat() {
const [errors, setErrors] = useState<ErrorState>({});
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const [noPengajuan, setNoPengajuan] = useState(""); const [noPengajuan, setNoPengajuan] = useState("");
const [submitLoading, setSubmitLoading] = useState(false); const [submitLoading, setSubmitLoading] = useState(false);
@@ -150,22 +153,24 @@ export default function FormSurat() {
}, [jenisSuratFix.id]); }, [jenisSuratFix.id]);
function onChecking() { function onChecking() {
const hasError = Object.values(errors).some((v) => v);
if (hasError) {
return notification({
title: "Gagal",
message: "Masih ada form yang belum valid",
type: "error",
});
}
const isFormKosong = Object.values(formSurat).some((value) => { const isFormKosong = Object.values(formSurat).some((value) => {
if (Array.isArray(value)) { if (Array.isArray(value)) {
return ( return value.some(
value.length === 0 || (item) =>
value.some( typeof item.value === "string" && item.value.trim() === "",
(item) =>
typeof item.value === "string" && item.value.trim() === "",
)
); );
} }
return typeof value === "string" && value.trim() === "";
if (typeof value === "string") {
return value.trim() === "";
}
return false;
}); });
if (isFormKosong) { if (isFormKosong) {
@@ -174,9 +179,9 @@ export default function FormSurat() {
message: "Silahkan lengkapi form surat", message: "Silahkan lengkapi form surat",
type: "error", type: "error",
}); });
} else {
open();
} }
open();
} }
async function onSubmit() { async function onSubmit() {
@@ -239,6 +244,30 @@ export default function FormSurat() {
); );
} }
function validateField(key: string, value: any) {
const stringValue = String(value ?? "").trim();
// wajib diisi
if (!stringValue) {
return "Field wajib diisi";
}
// 🔥 semua key yang mengandung "nik"
if (key.toLowerCase().includes("nik")) {
if (!/^\d+$/.test(stringValue)) {
return "NIK harus berupa angka";
}
if (stringValue.length !== 16) {
return "NIK harus 16 digit";
}
}
return null;
}
function validationForm({ function validationForm({
key, key,
value, value,
@@ -246,12 +275,26 @@ export default function FormSurat() {
key: "nama" | "phone" | "dataPelengkap" | "syaratDokumen"; key: "nama" | "phone" | "dataPelengkap" | "syaratDokumen";
value: any; value: any;
}) { }) {
if (key == "dataPelengkap" || key == "syaratDokumen") { if (key === "dataPelengkap" || key === "syaratDokumen") {
const errorMsg = validateField(value.key, value.value);
setErrors((prev) => ({
...prev,
[value.key]: errorMsg,
}));
setFormSurat((prev) => ({ setFormSurat((prev) => ({
...prev, ...prev,
[key]: updateArrayByKey(prev[key], value.key, value.value), [key]: updateArrayByKey(prev[key], value.key, value.value),
})); }));
} else { } else {
const errorMsg = validateField(key, value);
setErrors((prev) => ({
...prev,
[key]: errorMsg,
}));
setFormSurat({ setFormSurat({
...formSurat, ...formSurat,
[key]: value, [key]: value,
@@ -259,6 +302,7 @@ export default function FormSurat() {
} }
} }
return ( return (
<Container size="md" w={"100%"} pb={"lg"}> <Container size="md" w={"100%"} pb={"lg"}>
<Modal <Modal
@@ -358,6 +402,7 @@ export default function FormSurat() {
label={<FieldLabel label="Nama" hint="Nama kontak" />} label={<FieldLabel label="Nama" hint="Nama kontak" />}
placeholder="Budi Setiawan" placeholder="Budi Setiawan"
value={formSurat.nama} value={formSurat.nama}
error={errors.nama}
onChange={(e) => onChange={(e) =>
validationForm({ key: "nama", value: e.target.value }) validationForm({ key: "nama", value: e.target.value })
} }
@@ -374,6 +419,7 @@ export default function FormSurat() {
} }
placeholder="08123456789" placeholder="08123456789"
value={formSurat.phone} value={formSurat.phone}
error={errors.phone}
onChange={(e) => onChange={(e) =>
validationForm({ key: "phone", value: e.target.value }) validationForm({ key: "phone", value: e.target.value })
} }
@@ -446,6 +492,7 @@ export default function FormSurat() {
/> />
) : ( ) : (
<TextInput <TextInput
error={errors[item.key]}
type={item.type} type={item.type}
label={ label={
<FieldLabel <FieldLabel

View File

@@ -380,6 +380,7 @@ function DataUpdate({
}) { }) {
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const navigate = useNavigate(); const navigate = useNavigate();
const [errors, setErrors] = useState<Record<string, string | null>>({});
const [sukses, setSukses] = useState(false); const [sukses, setSukses] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false); const [submitLoading, setSubmitLoading] = useState(false);
const [dataPelengkap, setDataPelengkap] = useState<DataItem[]>([]); const [dataPelengkap, setDataPelengkap] = useState<DataItem[]>([]);
@@ -427,6 +428,29 @@ function DataUpdate({
fetchData(); fetchData();
}, []); }, []);
function validateField(key: string, value: any) {
const stringValue = String(value ?? "").trim();
// wajib diisi
if (!stringValue) {
return "Field wajib diisi";
}
// 🔥 semua key yg mengandung "nik"
if (key.toLowerCase().includes("nik")) {
if (!/^\d+$/.test(stringValue)) {
return "NIK harus berupa angka";
}
if (stringValue.length !== 16) {
return "NIK harus 16 digit";
}
}
return null;
}
function upsertById<T extends { id: string }>(array: T[], item: T): T[] { function upsertById<T extends { id: string }>(array: T[], item: T): T[] {
const index = array.findIndex((v) => v.id === item.id); const index = array.findIndex((v) => v.id === item.id);
@@ -446,6 +470,13 @@ function DataUpdate({
kategori: "dataPelengkap" | "syaratDokumen"; kategori: "dataPelengkap" | "syaratDokumen";
value: UpdateDataItem; value: UpdateDataItem;
}) { }) {
const errorMsg = validateField(value.key, value.value);
setErrors((prev) => ({
...prev,
[value.id]: errorMsg,
}));
setFormSurat((prev) => ({ setFormSurat((prev) => ({
...prev, ...prev,
[kategori]: upsertById(prev[kategori], { [kategori]: upsertById(prev[kategori], {
@@ -456,6 +487,7 @@ function DataUpdate({
})); }));
} }
function updateArrayByKey( function updateArrayByKey(
list: UpdateDataItem[], list: UpdateDataItem[],
id: string, id: string,
@@ -465,6 +497,16 @@ function DataUpdate({
} }
function onChecking() { function onChecking() {
const hasError = Object.values(errors).some((v) => v);
if (hasError) {
return notification({
title: "Gagal",
message: "Masih ada data yang belum valid",
type: "error",
});
}
if ( if (
formSurat.dataPelengkap.length == 0 && formSurat.dataPelengkap.length == 0 &&
formSurat.syaratDokumen.length == 0 formSurat.syaratDokumen.length == 0
@@ -675,8 +717,10 @@ function DataUpdate({
/> />
) : ( ) : (
<TextInput <TextInput
error={errors[item.id]}
label={<FieldLabel label={item.name} hint={item.desc} />} label={<FieldLabel label={item.name} hint={item.desc} />}
placeholder={item.name} placeholder={item.name}
type={item.type}
onChange={(e) => onChange={(e) =>
validationForm({ validationForm({
kategori: "dataPelengkap", kategori: "dataPelengkap",