MIF_E31222881/resources/js/Components/ModalInput.jsx

251 lines
12 KiB
JavaScript

import { Inertia } from "@inertiajs/inertia";
import React, { useState, useEffect } from "react";
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 value = e.target.value;
if (!selectedPayments.includes(value)) {
setSelectedPayments([...selectedPayments, value]);
const nominal = options.payment_nominal?.[value] || 0;
const penalty = options.payment_penalty?.[value] || 0;
setPaymentDetails({
...paymentDetails,
[value]: {
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()
// console.log("tableName:", tableName);
const formDataObj = new FormData()
Object.keys(formData).forEach((key) => {
if (key === 'foto' && !(formData[key] instanceof File)) {
return
}
formDataObj.append(key, formData[key])
})
if (initialData) {
Inertia.post(`/update${tableName}/${initialData.id}`, formDataObj, {
forceFormData: true,
onError: (errors) => setErrors(errors),
onSuccess: () => {
document.getElementById('modal_input').checked = false
setFormData({})
setErrors({})
onClose({})
}
})
} else {
Inertia.post(`/add${tableName}`, formDataObj, {
forceFormData: true,
onError: (errors) => setErrors(errors),
onSuccess: () => {
document.getElementById('modal_input').checked = false
setFormData({})
setErrors({})
}
})
}
}
return (
<div>
<input type="checkbox" id="modal_input" className="modal-toggle" />
<div className="modal" role="dialog">
<div className="modal-box">
<h2 className="font-bold text-lg text-center mb-5">
{initialData ? "Edit Data" : "Tambah Data"}
</h2>
<form onSubmit={handleSubmit} encType="multipart/form-data">
{Object.keys(fields).map((field) => (
<div key={field} className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
{field.replace("_", " ")}
{fields[field] === "select" ? (
<select
name={field}
value={formData[field] || ""}
onChange={handleChange}
className="select select-bordered w-full select-secondary"
>
<option disabled value="">
Pilih {field.replace("_", " ")}
</option>
{options[field] && Object.entries(options[field]).map(([key, value]) => (
<option key={key} value={key}>{value}</option>
))}
</select>
) : fields[field] === "file" ? (
<input
type="file"
name={field}
onChange={handleChange}
className="file-input file-input-bordered w-full file-input-secondary"
/>
) : (
fields[field] === "password" ? (
<input
type="password"
name={field}
onChange={handleChange}
value=""
className="grow border-none focus:ring-0"
placeholder="Kosongkan jika tidak ingin mengubah password"
/>
) : (
<input
type={fields[field]}
name={field}
value={formData[field] || ""}
onChange={handleChange}
className="grow border-none focus:ring-0"
placeholder={`Masukkan ${field.replace("_", " ")}`}
/>
)
)}
</label>
{errors[field] && <p className="text-red-500 text-sm">{errors[field]}</p>}
</div>
))}
{showPayments && (
<div>
<div className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
Payment Type
<select onChange={handlePaymentChange} className="select select-bordered w-full select-secondary">
<option disabled value="">Pilih Payment Type</option>
{options.payment_type &&
Object.entries(options.payment_type).map(([key, value]) => (
<option key={key} value={key}>{value}</option>
))}
</select>
</label>
</div>
{selectedPayments.map((paymentType) => (
<div key={paymentType} className="mb-2 border p-2 rounded relative">
<button
type="button"
onClick={() => handleRemovePayment(paymentType)}
className="absolute top-0 right-0 bg-red-500 text-white px-2 py-1 rounded-full text-xs"
>
X
</button>
<div className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
{options.payment_type[paymentType]} - Range Bulan
<input
type="number"
min="1"
value={paymentDetails[paymentType].range}
onChange={(e) => handleRangeChange(paymentType, parseInt(e.target.value))}
className="grow border-none focus:ring-0" name="range"
/>
</label>
</div>
<div className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
Nominal
<input type="text" value={paymentDetails[paymentType].nominal} readOnly className="grow border-none focus:ring-0 bg-gray-100" />
</label>
</div>
<div className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
Penalty
<input type="text" value={paymentDetails[paymentType].penalty} readOnly className="grow border-none focus:ring-0 bg-gray-100" />
</label>
</div>
</div>
))}
<div className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
Total Amount
<input
type="text"
value={Object.values(paymentDetails).reduce((sum, p) => sum + (p.amount || 0), 0)}
readOnly
className="grow border-none focus:ring-0 bg-gray-100"
/>
</label>
</div>
</div>
)}
<button type="submit" className="btn btn-secondary w-full mt-3">
{initialData ? "Simpan Perubahan" : "Tambah Data"}
</button>
</form>
</div>
<label className="modal-backdrop" htmlFor="modal_input">Close</label>
</div>
</div>
);
};
export default ModalInput