import { Inertia } from "@inertiajs/inertia"; import React, { useState, useEffect } from "react"; const getImageUrl = (foto) => { if (!foto) return null; if (typeof foto === 'string') return `${foto}`; return URL.createObjectURL(foto); }; const ModalInput = ({ fields, tableName, options, initialData, onClose, showPayments = false }) => { const [formData, setFormData] = useState({}); const [errors, setErrors] = useState({}); const [selectedPayments, setSelectedPayments] = useState([]); const [paymentDetails, setPaymentDetails] = useState({}); useEffect(() => { // console.log(initialData) setFormData(initialData || {}); setSelectedPayments([]); setPaymentDetails({}); }, [initialData]); const handleChange = (e) => { if (e.target.type === "file") { setFormData({ ...formData, [e.target.name]: e.target.files[0] }); } else { setFormData({ ...formData, [e.target.name]: e.target.value }); } }; // console.log(initialData) const handlePaymentChange = (e) => { const typeId = e.target.value; console.log(typeId) if (!selectedPayments.includes(typeId)) { setSelectedPayments([...selectedPayments, typeId]); const nominal = parseInt(options.payment_nominal[typeId]) || 0; const penalty = parseInt(options.payment_penalty[typeId]) || 0; setPaymentDetails({ ...paymentDetails, [typeId]: { range: 1, nominal, penalty, amount: nominal + penalty, }, }); } }; const handleRangeChange = (paymentType, newRange) => { setPaymentDetails((prevDetails) => { const validRange = newRange && !isNaN(newRange) ? Math.max(1, Number(newRange)) : 1; const currentDetails = prevDetails[paymentType] || { nominal: 0, penalty: 0 }; const newAmount = (currentDetails.nominal + currentDetails.penalty) * validRange; return { ...prevDetails, [paymentType]: { ...currentDetails, range: validRange, amount: newAmount, }, }; }); }; const handleRemovePayment = (paymentType) => { setSelectedPayments(selectedPayments.filter((p) => p !== paymentType)); const newDetails = { ...paymentDetails }; delete newDetails[paymentType]; setPaymentDetails(newDetails); }; const handleSubmit = (e) => { e.preventDefault(); const formDataObj = new FormData(); Object.keys(formData).forEach((key) => { if (key === 'foto' && !(formData[key] instanceof File)) { return; } formDataObj.append(key, formData[key]); }); if (showPayments) { const detailsArray = Object.entries(paymentDetails).map(([type_id, detail]) => ({ ...detail, type_id: parseInt(type_id) })); // Append items satu per satu detailsArray.forEach((item, index) => { formDataObj.append(`items[${index}][type_id]`, item.type_id); formDataObj.append(`items[${index}][range]`, item.range); // Kalau mau append nominal & penalty juga bisa, tapi biasanya backend gak butuh karena bisa hitung ulang }); } const url = initialData ? `/update${tableName}/${initialData.id}` : `/add${tableName}`; Inertia.post(url, formDataObj, { forceFormData: true, onError: (errors) => setErrors(errors), onSuccess: () => { document.getElementById('modal_input').checked = false; setFormData({}); setErrors({}); onClose({}); }, }); }; useEffect(() => { if (formData.foto instanceof File) { const url = URL.createObjectURL(formData.foto); return () => URL.revokeObjectURL(url); } }, [formData.foto]); return (

Form Data

{Object.entries(fields).map(([field, config]) => { const type = typeof config === "string" ? config : config.type; const readOnly = typeof config === "object" && config.readonly; return (
{type === "select" ? ( ) : type === "file" ? (
{field === 'foto' && (
{formData.foto && ( Preview Foto )}
)}
) : type === "password" ? ( ) : ( )} {errors[field] && (

{errors[field]}

)}
); })} {showPayments && (
{selectedPayments.map((paymentType) => (
handleRangeChange(paymentType, parseInt(e.target.value)) } className="input input-info w-full" name="range" />
))}
sum + (p.amount || 0), 0 )} readOnly className="input bg-gray-100 w-full" />
)}
); }; export default ModalInput