fix: enhance FilePreview component to limit filename display and add findLastEducation utility for education level mapping

This commit is contained in:
faisolavolut 2025-03-14 10:37:09 +07:00
parent c0dd392de0
commit 7f503e7050
5 changed files with 245 additions and 110 deletions

View File

@ -17,6 +17,7 @@ export const FormBetter: React.FC<any> = ({
className, className,
onInit, onInit,
afterLoad, afterLoad,
disabledScroll,
}) => { }) => {
const [fm, setFM] = useState<any>({ const [fm, setFM] = useState<any>({
data: null as any, data: null as any,
@ -37,6 +38,59 @@ export const FormBetter: React.FC<any> = ({
)} )}
<div className="w-full flex-grow flex flex-row rounded-lg"> <div className="w-full flex-grow flex flex-row rounded-lg">
<div className="w-full flex flex-row flex-grow bg-white rounded-lg border border-gray-300 relative "> <div className="w-full flex flex-row flex-grow bg-white rounded-lg border border-gray-300 relative ">
{disabledScroll ? (
<>
{" "}
<Form
{...{
children,
header,
onTitle,
onLoad: async () => {
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);
}
},
}}
/>
</>
) : (
<>
<ScrollArea className="flex-grow"> <ScrollArea className="flex-grow">
<Form <Form
{...{ {...{
@ -86,6 +140,8 @@ export const FormBetter: React.FC<any> = ({
}} }}
/> />
</ScrollArea> </ScrollArea>
</>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -242,7 +242,11 @@ export const FilePreview = ({
> >
<div className="flex flex-row gap-x-1 items-center"> <div className="flex flex-row gap-x-1 items-center">
<div className="h-[30px] flex flex-row items-center">{content}</div> <div className="h-[30px] flex flex-row items-center">{content}</div>
<div className="text-xs filename">{file?.name}</div> <div className="text-xs filename">
{limit_name && file?.name
? file?.name.substring(0, limit_name)
: file?.name}
</div>
</div> </div>
<div className="ml-2"> <div className="ml-2">

View File

@ -11,6 +11,7 @@ import { getNumber } from "@/lib/utils/getNumber";
import MaskedInput from "../../ui/MaskedInput"; import MaskedInput from "../../ui/MaskedInput";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { getLabel } from "@/lib/utils/getLabel"; import { getLabel } from "@/lib/utils/getLabel";
import { time } from "@/lib/utils/date";
export const TypeInput: React.FC<any> = ({ export const TypeInput: React.FC<any> = ({
name, name,
@ -30,7 +31,7 @@ export const TypeInput: React.FC<any> = ({
let value: any = fm.data?.[name] || ""; let value: any = fm.data?.[name] || "";
if (type === "time") { if (type === "time") {
value = convertToTimeOnly(value) || ""; value = time(value) || "";
} }
const [rating, setRating] = useState(value); // State untuk menyimpan nilai rating const [rating, setRating] = useState(value); // State untuk menyimpan nilai rating
const handleClick = (index: number) => { const handleClick = (index: number) => {
@ -70,7 +71,7 @@ export const TypeInput: React.FC<any> = ({
meta.rgbValue = convertColor.toRgbString(); meta.rgbValue = convertColor.toRgbString();
meta.render(); meta.render();
} else if (type === "time") { } 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(); fm.render();
} else { } else {
setRating(value ? value - 1 : value); setRating(value ? value - 1 : value);
@ -246,7 +247,8 @@ export const TypeInput: React.FC<any> = ({
); );
break; break;
case "money": case "money":
return <> return (
<>
<Input <Input
id={name} id={name}
name={name} name={name}
@ -300,7 +302,8 @@ export const TypeInput: React.FC<any> = ({
} }
}} }}
/> />
</>; </>
);
break; break;
} }
let type_field = type; let type_field = type;

View File

@ -80,6 +80,7 @@ const styles = StyleSheet.create({
}); });
// Create Document Component // Create Document Component
export const DocumentBiodata: FC<any> = ({ data, onRender }) => { export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
console.log({ data });
return ( return (
<PDFViewer className="flex-grow w-full"> <PDFViewer className="flex-grow w-full">
<Document <Document
@ -134,8 +135,14 @@ export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
<Text>DATA DIRI </Text> <Text>DATA DIRI </Text>
</View> </View>
{[ {[
{ label: "Nama Lengkap 姓名", value: "" }, { label: "Nama Lengkap 姓名", value: data?.name },
{ label: "Tempat & Tanggal Lahir 出生地点,日期", value: "" }, {
label: "Tempat & Tanggal Lahir 出生地点,日期",
value:
data?.birth_place && data?.birth_date
? `${data?.birth_place}, ${dayDate(data?.birth_date)}`
: "",
},
].map((row: any, rowIndex) => { ].map((row: any, rowIndex) => {
return <RowPDF row={row} rowIndex={rowIndex} key={rowIndex} />; return <RowPDF row={row} rowIndex={rowIndex} key={rowIndex} />;
})} })}
@ -159,7 +166,12 @@ export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
[ [
{ {
label: "Jenis Kelamin 性别", label: "Jenis Kelamin 性别",
value: "L 男 / P 女", value:
data?.gender === "FEMALE"
? "P 女"
: data?.gender === "MALE"
? "L 男"
: "L 男 / P 女",
mode: "noline", mode: "noline",
}, },
{ {
@ -180,7 +192,7 @@ export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
], ],
[ [
{ label: "No. KTP 身份证号码", value: "" }, { label: "No. KTP 身份证号码", value: "" },
{ label: "Agama 宗教", value: "" }, { label: "Agama 宗教", value: data?.religion },
], ],
[ [
{ label: "Masa Berlaku KTP 身份证有效期", value: "" }, { label: "Masa Berlaku KTP 身份证有效期", value: "" },
@ -202,9 +214,9 @@ export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
value: "", value: "",
// mode: "placeholder", // mode: "placeholder",
}, },
{ label: "Alamat Lengkap 地址", value: "" }, { label: "Alamat Lengkap 地址", value: data?.address },
{ label: "Alamat Lengkap Asal 故乡地址", value: "" }, { label: "Alamat Lengkap Asal 故乡地址", value: "" },
{ label: "Alamat Email 电子邮件地址", value: "" }, { label: "Alamat Email 电子邮件地址", value: data?.user?.email },
].map((row: any, rowIndex) => { ].map((row: any, rowIndex) => {
return <RowPDF row={row} rowIndex={rowIndex} key={rowIndex} />; return <RowPDF row={row} rowIndex={rowIndex} key={rowIndex} />;
})} })}
@ -726,7 +738,9 @@ export const DocumentBiodata: FC<any> = ({ data, onRender }) => {
borderRight: 1, borderRight: 1,
borderColor: "black", borderColor: "black",
}} }}
></Text> >
{}
</Text>
<Text <Text
style={{ style={{
width: 200, width: 200,

View File

@ -0,0 +1,58 @@
export const findLastEducation = (searchTerm: string, userEducation: any[]) => {
if (!Array.isArray(userEducation) || userEducation.length === 0) {
return null; // Jika array kosong, kembalikan null
}
const educationMapping: Record<string, string | string[]> = {
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
);
}
};