From 7f503e7050165a3cd9039b1e2f9d902fc66e90f8 Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Fri, 14 Mar 2025 10:37:09 +0700 Subject: [PATCH] fix: enhance FilePreview component to limit filename display and add findLastEducation utility for education level mapping --- components/form/FormBetter.tsx | 148 ++++++++++++++++++-------- components/form/field/FilePreview.tsx | 6 +- components/form/field/TypeInput.tsx | 115 ++++++++++---------- components/ui/DocumentBiodata.tsx | 28 +++-- utils/findLastEducation.ts | 58 ++++++++++ 5 files changed, 245 insertions(+), 110 deletions(-) create mode 100644 utils/findLastEducation.ts diff --git a/components/form/FormBetter.tsx b/components/form/FormBetter.tsx index 007582c..2217dfe 100644 --- a/components/form/FormBetter.tsx +++ b/components/form/FormBetter.tsx @@ -17,6 +17,7 @@ export const FormBetter: React.FC = ({ className, onInit, afterLoad, + disabledScroll, }) => { const [fm, setFM] = useState({ data: null as any, @@ -37,55 +38,110 @@ export const FormBetter: React.FC = ({ )}
- -
{ - try { - const res = await onLoad(); - return res; - } catch (ex: any) { - setShow(false); - throw new Error( - get(ex, "response.data.meta.message") || ex.message - ); - } - }, - onSubmit, - onFooter, - showResize, - mode, - className: cx(className, "top-0 left-0 w-full"), - afterLoad, - onInit: (form: any) => { - setFM(form); + {disabledScroll ? ( + <> + {" "} + { + try { + const res = await onLoad(); + return res; + } catch (ex: any) { + setShow(false); + throw new Error( + get(ex, "response.data.meta.message") || ex.message + ); + } + }, + onSubmit, + onFooter, + showResize, + mode, + className: cx(className, "top-0 left-0 w-full"), + afterLoad, + onInit: (form: any) => { + setFM(form); - const originalRender = form.render; + const originalRender = form.render; - // Buat versi baru dari `local.render` - form.render = () => { - // Panggil fungsi asli - originalRender(); + // Buat versi baru dari `local.render` + form.render = () => { + // Panggil fungsi asli + originalRender(); - // Tambahkan logika tambahan untuk sinkronisasi - setFM({ - ...form, - submit: form.submit, - render: form.render, - data: form.data, - }); - }; - form.render(); - if (typeof onInit === "function") { - onInit(form); - } - }, - }} - /> - + // Tambahkan logika tambahan untuk sinkronisasi + setFM({ + ...form, + submit: form.submit, + render: form.render, + data: form.data, + }); + }; + form.render(); + if (typeof onInit === "function") { + onInit(form); + } + }, + }} + /> + + ) : ( + <> + + { + try { + const res = await onLoad(); + return res; + } catch (ex: any) { + setShow(false); + throw new Error( + get(ex, "response.data.meta.message") || ex.message + ); + } + }, + onSubmit, + onFooter, + showResize, + mode, + className: cx(className, "top-0 left-0 w-full"), + afterLoad, + onInit: (form: any) => { + setFM(form); + + const originalRender = form.render; + + // Buat versi baru dari `local.render` + form.render = () => { + // Panggil fungsi asli + originalRender(); + + // Tambahkan logika tambahan untuk sinkronisasi + setFM({ + ...form, + submit: form.submit, + render: form.render, + data: form.data, + }); + }; + form.render(); + if (typeof onInit === "function") { + onInit(form); + } + }, + }} + /> + + + )}
diff --git a/components/form/field/FilePreview.tsx b/components/form/field/FilePreview.tsx index 02b043a..c917f54 100644 --- a/components/form/field/FilePreview.tsx +++ b/components/form/field/FilePreview.tsx @@ -242,7 +242,11 @@ export const FilePreview = ({ >
{content}
-
{file?.name}
+
+ {limit_name && file?.name + ? file?.name.substring(0, limit_name) + : file?.name} +
diff --git a/components/form/field/TypeInput.tsx b/components/form/field/TypeInput.tsx index 4e5c4cb..03e194d 100644 --- a/components/form/field/TypeInput.tsx +++ b/components/form/field/TypeInput.tsx @@ -11,6 +11,7 @@ import { getNumber } from "@/lib/utils/getNumber"; import MaskedInput from "../../ui/MaskedInput"; import { cn } from "@/lib/utils"; import { getLabel } from "@/lib/utils/getLabel"; +import { time } from "@/lib/utils/date"; export const TypeInput: React.FC = ({ name, @@ -30,7 +31,7 @@ export const TypeInput: React.FC = ({ let value: any = fm.data?.[name] || ""; if (type === "time") { - value = convertToTimeOnly(value) || ""; + value = time(value) || ""; } const [rating, setRating] = useState(value); // State untuk menyimpan nilai rating const handleClick = (index: number) => { @@ -70,7 +71,7 @@ export const TypeInput: React.FC = ({ meta.rgbValue = convertColor.toRgbString(); meta.render(); } else if (type === "time") { - if (fm.data?.[name]) fm.data[name] = convertToTimeOnly(fm.data[name]); + if (fm.data?.[name]) fm.data[name] = time(fm.data[name]); fm.render(); } else { setRating(value ? value - 1 : value); @@ -246,61 +247,63 @@ export const TypeInput: React.FC = ({ ); break; case "money": - return <> - { - const rawValue = ev.currentTarget.value - .replace(/[^0-9,-]/g, "") - .toString(); - if (rawValue === "0") { - input.value = "0"; - input.render(); - } - if ( - (!rawValue.startsWith(",") || !rawValue.endsWith(",")) && - !rawValue.endsWith("-") && - convertionCurrencyNumber(rawValue) !== - convertionCurrencyNumber(input.value) - ) { - fm.data[name] = convertionCurrencyNumber( - formatCurrency(rawValue) - ); - fm.render(); - if (typeof onChange === "function") { - onChange(fm.data[name]); + return ( + <> + { + const rawValue = ev.currentTarget.value + .replace(/[^0-9,-]/g, "") + .toString(); + if (rawValue === "0") { + input.value = "0"; + input.render(); } - input.value = formatCurrency(fm.data[name]); - input.render(); - } else { - input.value = rawValue; - input.render(); - } - }} - /> - ; + if ( + (!rawValue.startsWith(",") || !rawValue.endsWith(",")) && + !rawValue.endsWith("-") && + convertionCurrencyNumber(rawValue) !== + convertionCurrencyNumber(input.value) + ) { + fm.data[name] = convertionCurrencyNumber( + formatCurrency(rawValue) + ); + fm.render(); + if (typeof onChange === "function") { + onChange(fm.data[name]); + } + input.value = formatCurrency(fm.data[name]); + input.render(); + } else { + input.value = rawValue; + input.render(); + } + }} + /> + + ); break; } let type_field = type; diff --git a/components/ui/DocumentBiodata.tsx b/components/ui/DocumentBiodata.tsx index eafd969..2572181 100644 --- a/components/ui/DocumentBiodata.tsx +++ b/components/ui/DocumentBiodata.tsx @@ -80,6 +80,7 @@ const styles = StyleSheet.create({ }); // Create Document Component export const DocumentBiodata: FC = ({ data, onRender }) => { + console.log({ data }); return ( = ({ data, onRender }) => { DATA DIRI 个人资料 {[ - { label: "Nama Lengkap 姓名", value: "" }, - { label: "Tempat & Tanggal Lahir 出生地点,日期", value: "" }, + { label: "Nama Lengkap 姓名", value: data?.name }, + { + label: "Tempat & Tanggal Lahir 出生地点,日期", + value: + data?.birth_place && data?.birth_date + ? `${data?.birth_place}, ${dayDate(data?.birth_date)}` + : "", + }, ].map((row: any, rowIndex) => { return ; })} @@ -159,7 +166,12 @@ export const DocumentBiodata: FC = ({ data, onRender }) => { [ { label: "Jenis Kelamin 性别", - value: "L 男 / P 女", + value: + data?.gender === "FEMALE" + ? "P 女" + : data?.gender === "MALE" + ? "L 男" + : "L 男 / P 女", mode: "noline", }, { @@ -180,7 +192,7 @@ export const DocumentBiodata: FC = ({ data, onRender }) => { ], [ { label: "No. KTP 身份证号码", value: "" }, - { label: "Agama 宗教", value: "" }, + { label: "Agama 宗教", value: data?.religion }, ], [ { label: "Masa Berlaku KTP 身份证有效期", value: "" }, @@ -202,9 +214,9 @@ export const DocumentBiodata: FC = ({ data, onRender }) => { value: "", // mode: "placeholder", }, - { label: "Alamat Lengkap 地址", value: "" }, + { label: "Alamat Lengkap 地址", value: data?.address }, { label: "Alamat Lengkap Asal 故乡地址", value: "" }, - { label: "Alamat Email 电子邮件地址", value: "" }, + { label: "Alamat Email 电子邮件地址", value: data?.user?.email }, ].map((row: any, rowIndex) => { return ; })} @@ -726,7 +738,9 @@ export const DocumentBiodata: FC = ({ data, onRender }) => { borderRight: 1, borderColor: "black", }} - > + > + {} + { + if (!Array.isArray(userEducation) || userEducation.length === 0) { + return null; // Jika array kosong, kembalikan null + } + + const educationMapping: Record = { + SD: "10 - Junior High School", + SLTP: "9 - Senior High School", + SLTA: "3 - Bachelor", + "D 1": "4 - Diploma 1", + "D 2": "5 - Diploma 2", + "D 3": "6 - Diploma 3", + "D 1/2/3": ["4 - Diploma 1", "5 - Diploma 2", "6 - Diploma 3"], // Cari D1/D2/D3 tertinggi & terbaru + S1: ["3 - Bachelor", "7 - Diploma 4"], // S1 setara dengan D4 + S2: "2 - Master Degree", + S3: "1 - Doctoral / Professor", + }; + + const mappedValue = educationMapping[searchTerm]; + if (!mappedValue) return null; + + let filteredEducations; + + if (Array.isArray(mappedValue)) { + // Jika "D 1/2/3" atau "S1" (D4) + filteredEducations = userEducation.filter((edu) => + mappedValue.includes(edu.education_level) + ); + if (filteredEducations.length === 0) return null; + + // Pilih jenjang tertinggi, jika sama maka pilih graduate_year terbaru + return filteredEducations.reduce((highest, current) => { + const highestIndex = mappedValue.indexOf(highest.education_level); + const currentIndex = mappedValue.indexOf(current.education_level); + + if (currentIndex > highestIndex) { + return current; + } + if (currentIndex === highestIndex) { + return current.graduate_year > highest.graduate_year + ? current + : highest; + } + return highest; + }); + } else { + // Jika hanya satu jenjang (misalnya SD, SLTP, SLTA, S2, S3) + filteredEducations = userEducation.filter( + (edu) => edu.education_level === mappedValue + ); + if (filteredEducations.length === 0) return null; + + // Pilih graduate_year terbaru + return filteredEducations.reduce((latest, current) => + current.graduate_year > latest.graduate_year ? current : latest + ); + } +};