osaka/src/pages/ChargeEdit.jsx

185 lines
4.8 KiB
JavaScript

import { useState, useEffect } from "react";
import { useLoading } from "../hooks/useLoading";
import FormField from "../components/FormField";
import FormInput from "../components/FormInput";
import FormSelect from "../components/FormSelect";
import Button from "../components/Button";
import FormBox from "../components/FormBox";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom";
import { lockerService } from "../services/locker.service";
import { AnimatePresence } from "motion/react";
import { Pencil } from "lucide-react";
import Notification from "../components/Notification";
import FieldsWrapper from "../components/FieldsWrapper";
function ChargeEdit() {
const [chargeDetails, setChargeDetails] = useState({
rentAmount: "",
rentAmountEdit: false,
penaltyAmount: "",
penaltyAmountEdit: false,
});
const [notification, setNotification] = useState({ message: "", type: "" });
const { setIsLoading } = useLoading();
const { t } = useTranslation();
const location = useLocation();
const productCode = location.state?.productCode;
const interestCategory = location.state?.interestCategory;
useEffect(() => {
const fetchCharges = async () => {
try {
setIsLoading(true);
const response = await lockerService.getCharges(
productCode,
interestCategory
);
if (response.status === 200) {
const { rent, penalty } = response.data;
setChargeDetails({
rentAmount: rent.toString(),
rentAmountEdit: false,
penaltyAmount: penalty.toString(),
penaltyAmountEdit: false,
});
} else {
setNotification({
message: response.data.message,
type: "error",
});
}
} catch (error) {
console.error(error);
setNotification({
message: error.message,
type: "error",
});
} finally {
setIsLoading(false);
}
};
fetchCharges();
}, [productCode, interestCategory, setIsLoading]);
if (!location.state) {
return <></>;
}
const formFields = [
{
name: "rentAmount",
label: "Rent Amount",
type: "input",
subType: "number",
readOnly: !chargeDetails.rentAmountEdit,
icon: {
icon: <Pencil size={22} />,
mode: "plain",
onClick: () => {
setChargeDetails({ ...chargeDetails, rentAmountEdit: true });
},
},
},
{
name: "penaltyAmount",
label: "Penalty Amount",
type: "input",
subType: "number",
readOnly: !chargeDetails.penaltyAmountEdit,
icon: {
icon: <Pencil size={22} />,
mode: "plain",
onClick: () => {
setChargeDetails({ ...chargeDetails, penaltyAmountEdit: true });
},
},
},
];
const handleSubmit = async (e) => {
e.preventDefault();
try {
setIsLoading(true);
const response = await lockerService.updateCharges(
productCode,
interestCategory,
chargeDetails.rentAmount,
chargeDetails.penaltyAmount
);
if (response.status === 200) {
setNotification({
message: response.data.message,
type: "success",
});
} else {
setNotification({
message: response.data.message,
type: "error",
});
}
} catch (error) {
console.error(error);
setNotification({
message: error.message,
type: "error",
});
} finally {
setIsLoading(false);
}
};
const renderField = (field) => {
const commonProps = {
value: chargeDetails[field.name],
onChange: (e) => {
setChargeDetails({
...chargeDetails,
[field.name]: e.target.value,
});
},
readOnly: field.readOnly,
type: field.subType,
};
const className = field.readOnly ? "bg-grey/[0.3]" : "";
return (
<FormField key={field.name} label={field.label} icon={field.icon}>
{field.type === "input" ? (
<FormInput props={commonProps} className={className} />
) : (
<FormSelect
props={commonProps}
options={field.options}
className={className}
/>
)}
</FormField>
);
};
return (
<div>
<AnimatePresence>
{notification.message !== "" && <Notification {...notification} />}
</AnimatePresence>
<FormBox title={t("chargeEdit")}>
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
<Button
text={t("submit")}
onClick={handleSubmit}
disabled={
!chargeDetails.rentAmountEdit && !chargeDetails.penaltyAmountEdit
}
/>
</FormBox>
</div>
);
}
export default ChargeEdit;