done
This commit is contained in:
parent
5176cde471
commit
4adf7fe668
|
@ -45,7 +45,7 @@ const propertySchema = mongoose.Schema({
|
||||||
// Remove individual property tax fields and replace with array
|
// Remove individual property tax fields and replace with array
|
||||||
propertyTaxInfo: [propertyTaxInfoSchema], // Array of tax info objects
|
propertyTaxInfo: [propertyTaxInfoSchema], // Array of tax info objects
|
||||||
images: [imageSchema],
|
images: [imageSchema],
|
||||||
googleMapLink: { type: String },
|
googleMapLink: { type: String },
|
||||||
userfirstname: String,
|
userfirstname: String,
|
||||||
usermiddlename: String,
|
usermiddlename: String,
|
||||||
userlastname: String,
|
userlastname: String,
|
||||||
|
@ -98,7 +98,7 @@ const propertySchema = mongoose.Schema({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
totalcredits:{
|
totalcredits: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true, // Set to true if this field is mandatory
|
required: true, // Set to true if this field is mandatory
|
||||||
},
|
},
|
||||||
|
@ -106,7 +106,7 @@ const propertySchema = mongoose.Schema({
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true, // Set to true if this field is mandatory
|
required: true, // Set to true if this field is mandatory
|
||||||
},
|
},
|
||||||
incidentalCost:[
|
incidentalCost: [
|
||||||
{
|
{
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -122,6 +122,22 @@ const propertySchema = mongoose.Schema({
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true, // Set to true if this field is mandatory
|
required: true, // Set to true if this field is mandatory
|
||||||
},
|
},
|
||||||
|
utilMaintenance: [
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true, // Set to true if this field is mandatory
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
type: Number,
|
||||||
|
required: true, // Set to true if this field is mandatory
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
totalutilMaintenanceCost: {
|
||||||
|
type: Number,
|
||||||
|
required: true, // Set to true if this field is mandatory
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const PropertyModal = mongoose.model("property", propertySchema);
|
const PropertyModal = mongoose.model("property", propertySchema);
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-BQhPskw6.js"></script>
|
<script type="module" crossorigin src="/assets/index-BXhlX8aB.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,22 @@ const Addproperty = () => {
|
||||||
{ title: "Property Taxes", price: "" },
|
{ title: "Property Taxes", price: "" },
|
||||||
{ title: "Travel Expenses", price: "" },
|
{ title: "Travel Expenses", price: "" },
|
||||||
],
|
],
|
||||||
|
utilMaintenance: [
|
||||||
|
{ title: "Electricity", price: "" },
|
||||||
|
{ title: "Water and Sewer", price: "" },
|
||||||
|
{ title: "Natural Gas", price: "" },
|
||||||
|
{ title: "Trash and Recycling", price: "" },
|
||||||
|
{ title: "Internet and Cable", price: "" },
|
||||||
|
{ title: "Heating Oil/Propane", price: "" },
|
||||||
|
{ title: "HOA fees", price: "" },
|
||||||
|
{ title: "Dump fees", price: "" },
|
||||||
|
{ title: "Insurance", price: "" },
|
||||||
|
{ title: "Interest on Loans", price: "" },
|
||||||
|
{ title: "Loan Payment", price: "" },
|
||||||
|
{ title: "Property Taxes", price: "" },
|
||||||
|
{ title: "Security", price: "" },
|
||||||
|
{ title: "Real Estates fees", price: "" },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const [submitted, setSubmitted] = useState(false);
|
const [submitted, setSubmitted] = useState(false);
|
||||||
|
@ -212,13 +228,12 @@ const Addproperty = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const calculateTotalCredits = () => {
|
||||||
const calculateTotalCredits = () => {
|
return formData.credits.reduce((total, credits) => {
|
||||||
return formData.credits.reduce((total, credits) => {
|
const price = parseFloat(credits.price);
|
||||||
const price = parseFloat(credits.price);
|
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||||||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
}, 0);
|
||||||
}, 0);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const calculateTotalCostsWithCredits = () => {
|
const calculateTotalCostsWithCredits = () => {
|
||||||
// Calculate total from costPaidAtoB array
|
// Calculate total from costPaidAtoB array
|
||||||
|
@ -240,8 +255,6 @@ const Addproperty = () => {
|
||||||
return totalCostsFromArray + totalCreditsFromArray + purchaseCost;
|
return totalCostsFromArray + totalCreditsFromArray + purchaseCost;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const addincidentalCost = () => {
|
const addincidentalCost = () => {
|
||||||
setFormData((prevData) => ({
|
setFormData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
|
@ -250,7 +263,9 @@ const Addproperty = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteincidentalCost = (index) => {
|
const deleteincidentalCost = (index) => {
|
||||||
const updatedincidentalCost = formData.incidentalCost.filter((_, i) => i !== index);
|
const updatedincidentalCost = formData.incidentalCost.filter(
|
||||||
|
(_, i) => i !== index
|
||||||
|
);
|
||||||
setFormData((prevData) => ({
|
setFormData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
incidentalCost: updatedincidentalCost,
|
incidentalCost: updatedincidentalCost,
|
||||||
|
@ -275,29 +290,92 @@ const Addproperty = () => {
|
||||||
|
|
||||||
// If valid number, update state, otherwise show the alert
|
// If valid number, update state, otherwise show the alert
|
||||||
if (isNumber || value === "") {
|
if (isNumber || value === "") {
|
||||||
const updatedincidentalCost = formData.incidentalCost.map((incidentalCost, i) =>
|
const updatedincidentalCost = formData.incidentalCost.map(
|
||||||
i === index
|
(incidentalCost, i) =>
|
||||||
? { ...incidentalCost, price: value, isInvalid: false } // Reset isInvalid if valid number
|
i === index
|
||||||
: incidentalCost
|
? { ...incidentalCost, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||||||
|
: incidentalCost
|
||||||
);
|
);
|
||||||
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
||||||
} else {
|
} else {
|
||||||
const updatedincidentalCost = formData.incidentalCost.map((incidentalCost, i) =>
|
const updatedincidentalCost = formData.incidentalCost.map(
|
||||||
i === index
|
(incidentalCost, i) =>
|
||||||
? { ...incidentalCost, isInvalid: true } // Set isInvalid true for invalid input
|
i === index
|
||||||
: incidentalCost
|
? { ...incidentalCost, isInvalid: true } // Set isInvalid true for invalid input
|
||||||
|
: incidentalCost
|
||||||
);
|
);
|
||||||
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate total from incidentalCost array
|
// Calculate total from incidentalCost array
|
||||||
const calculateTotalincidentalCost = () => {
|
const calculateTotalincidentalCost = () => {
|
||||||
return formData.incidentalCost.reduce((total, incidentalCost) => {
|
return formData.incidentalCost.reduce((total, incidentalCost) => {
|
||||||
const price = parseFloat(incidentalCost.price);
|
const price = parseFloat(incidentalCost.price);
|
||||||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addutilMaintenanceCost = () => {
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
utilMaintenance: [...prevData.utilMaintenance, { title: "", price: "" }],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteutilMaintenanceCost = (index) => {
|
||||||
|
const updatedutilMaintenance = formData.utilMaintenance.filter(
|
||||||
|
(_, i) => i !== index
|
||||||
|
);
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
utilMaintenance: updatedutilMaintenance,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to handle changes to incidentalCost title and price
|
||||||
|
const handleutilMaintenanceTitle = (index, field, value) => {
|
||||||
|
const updatedutilMaintenance = [...formData.utilMaintenance];
|
||||||
|
updatedutilMaintenance[index][field] = value;
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
utilMaintenance: updatedutilMaintenance,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleutilMaintenanceCostChange = (e, index) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
|
||||||
|
// Regular expression to allow only numbers and optional decimals
|
||||||
|
const isNumber = /^\d*\.?\d*$/.test(value);
|
||||||
|
|
||||||
|
// If valid number, update state, otherwise show the alert
|
||||||
|
if (isNumber || value === "") {
|
||||||
|
const updatedutilMaintenance = formData.utilMaintenance.map(
|
||||||
|
(utilMaintenance, i) =>
|
||||||
|
i === index
|
||||||
|
? { ...utilMaintenance, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||||||
|
: utilMaintenance
|
||||||
|
);
|
||||||
|
setFormData({ ...formData, utilMaintenance: updatedutilMaintenance });
|
||||||
|
} else {
|
||||||
|
const updatedutilMaintenance = formData.utilMaintenance.map(
|
||||||
|
(utilMaintenance, i) =>
|
||||||
|
i === index
|
||||||
|
? { ...utilMaintenance, isInvalid: true } // Set isInvalid true for invalid input
|
||||||
|
: utilMaintenance
|
||||||
|
);
|
||||||
|
setFormData({ ...formData, utilMaintenance: updatedutilMaintenance });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate total from incidentalCost array
|
||||||
|
const calculatetotalutilMaintenanceCost = () => {
|
||||||
|
return formData.utilMaintenance.reduce((total, utilMaintenance) => {
|
||||||
|
const price = parseFloat(utilMaintenance.price);
|
||||||
|
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (
|
if (
|
||||||
|
@ -332,7 +410,8 @@ const Addproperty = () => {
|
||||||
const totalCostsAtoB = calculateTotalCosts();
|
const totalCostsAtoB = calculateTotalCosts();
|
||||||
const totalCostsAtoBaftercredits = calculateTotalCostsWithCredits();
|
const totalCostsAtoBaftercredits = calculateTotalCostsWithCredits();
|
||||||
const totalincidentalCost = calculateTotalincidentalCost();
|
const totalincidentalCost = calculateTotalincidentalCost();
|
||||||
const totalcredits= calculateTotalCredits();
|
const totalcredits = calculateTotalCredits();
|
||||||
|
const totalutilMaintenanceCost = calculatetotalutilMaintenanceCost();
|
||||||
|
|
||||||
// Add user info to formData, including the propertyTaxInfo array
|
// Add user info to formData, including the propertyTaxInfo array
|
||||||
const formDataWithUserInfo = {
|
const formDataWithUserInfo = {
|
||||||
|
@ -344,9 +423,10 @@ const Addproperty = () => {
|
||||||
useremail: user?.result?.email,
|
useremail: user?.result?.email,
|
||||||
userId: user?.result?.userId,
|
userId: user?.result?.userId,
|
||||||
totalCostsAtoB: totalCostsAtoB,
|
totalCostsAtoB: totalCostsAtoB,
|
||||||
totalcredits:totalcredits,
|
totalcredits: totalcredits,
|
||||||
totalCostsAtoBaftercredits: totalCostsAtoBaftercredits,
|
totalCostsAtoBaftercredits: totalCostsAtoBaftercredits,
|
||||||
totalincidentalCost:totalincidentalCost,
|
totalincidentalCost: totalincidentalCost,
|
||||||
|
totalutilMaintenanceCost: totalutilMaintenanceCost,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if propertyTaxInfo is an array and has values
|
// Check if propertyTaxInfo is an array and has values
|
||||||
|
@ -1498,7 +1578,6 @@ const Addproperty = () => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="row gy-3 align-items-center">
|
<div className="row gy-3 align-items-center">
|
||||||
<span
|
<span
|
||||||
className="col-md-4"
|
className="col-md-4"
|
||||||
|
@ -1529,8 +1608,6 @@ const Addproperty = () => {
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className="row gy-3 align-items-center">
|
<div className="row gy-3 align-items-center">
|
||||||
<span
|
<span
|
||||||
className="col-md-4"
|
className="col-md-4"
|
||||||
|
@ -1562,7 +1639,6 @@ const Addproperty = () => {
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: "#fda417",
|
color: "#fda417",
|
||||||
|
@ -1581,7 +1657,11 @@ const Addproperty = () => {
|
||||||
className="form-control"
|
className="form-control"
|
||||||
value={cost.title}
|
value={cost.title}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleincidentalCostTitle(index, "title", e.target.value)
|
handleincidentalCostTitle(
|
||||||
|
index,
|
||||||
|
"title",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
}
|
}
|
||||||
placeholder="Title"
|
placeholder="Title"
|
||||||
required
|
required
|
||||||
|
@ -1608,7 +1688,7 @@ const Addproperty = () => {
|
||||||
<div className="col-md-2 d-flex justify-content-start">
|
<div className="col-md-2 d-flex justify-content-start">
|
||||||
<button
|
<button
|
||||||
className="btn btn-danger"
|
className="btn btn-danger"
|
||||||
onClick={() => deleteincidentalCost (index)}
|
onClick={() => deleteincidentalCost(index)}
|
||||||
style={{ marginLeft: "5px" }}
|
style={{ marginLeft: "5px" }}
|
||||||
>
|
>
|
||||||
x
|
x
|
||||||
|
@ -1635,7 +1715,6 @@ const Addproperty = () => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="row gy-3 align-items-center">
|
<div className="row gy-3 align-items-center">
|
||||||
<span
|
<span
|
||||||
className="col-md-4"
|
className="col-md-4"
|
||||||
|
@ -1663,11 +1742,118 @@ const Addproperty = () => {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
color: "#fda417",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Utilities & Maintenance:
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{formData.utilMaintenance.map((cost, index) => (
|
||||||
|
<div key={index} className="row gy-3 align-items-center">
|
||||||
|
<div className="col-md-4">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
value={cost.title}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleutilMaintenanceTitle(
|
||||||
|
index,
|
||||||
|
"title",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="Title"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={`form-control ${
|
||||||
|
cost.isInvalid ? "is-invalid" : ""
|
||||||
|
}`} // Apply 'is-invalid' class when invalid
|
||||||
|
value={cost.price}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleutilMaintenanceCostChange(e, index)
|
||||||
|
} // Use a new handler for price validation
|
||||||
|
placeholder="Price"
|
||||||
|
style={{ textAlign: "right" }}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{cost.isInvalid && (
|
||||||
|
<div className="invalid-feedback">
|
||||||
|
Please enter a valid number.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 d-flex justify-content-start">
|
||||||
|
<button
|
||||||
|
className="btn btn-danger"
|
||||||
|
onClick={() => deleteutilMaintenanceCost(index)}
|
||||||
|
style={{ marginLeft: "5px" }}
|
||||||
|
>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="col-md-4">
|
||||||
|
<button
|
||||||
|
className="btn btn-primary back"
|
||||||
|
onClick={addutilMaintenanceCost}
|
||||||
|
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: "20px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</span>{" "}
|
||||||
|
Add Utilities and Maintenance Cost
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row gy-3 align-items-center">
|
||||||
|
<span
|
||||||
|
className="col-md-4"
|
||||||
|
style={{
|
||||||
|
color: "#fda417",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Total Utilities and Maintenance Cost
|
||||||
|
</span>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
name="totalutilMaintenanceCost"
|
||||||
|
value={calculatetotalutilMaintenanceCost()}
|
||||||
|
readOnly
|
||||||
|
style={{
|
||||||
|
borderColor: "#fda417", // Custom border color for the input field
|
||||||
|
color: "#fda417", // Optionally apply text color to the input text
|
||||||
|
textAlign: "right",
|
||||||
|
}}
|
||||||
|
// placeholder="Total Incidental Cost"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
<button
|
<button
|
||||||
|
|
Loading…
Reference in New Issue