This commit is contained in:
omkieit 2024-10-12 14:54:41 +05:30
parent c8d2af7902
commit b758b3a1b9
6 changed files with 266 additions and 165 deletions

View File

@ -82,6 +82,10 @@ 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
}, },
rateofreturn :{
type: Number,
required: true, // Set to true if this field is mandatory
},
costPaidAtoB: [ costPaidAtoB: [
{ {
title: { title: {

File diff suppressed because one or more lines are too long

View File

@ -45,7 +45,7 @@
<script type="module" crossorigin src="/assets/index-qn9aVrHm.js"></script> <script type="module" crossorigin src="/assets/index-DrhA6SgP.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css"> <link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
</head> </head>

View File

@ -16,6 +16,7 @@
"ef-ui": "file:", "ef-ui": "file:",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"mdb-react-ui-kit": "^8.0.0", "mdb-react-ui-kit": "^8.0.0",
"moment": "^2.30.1",
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^18.3.1", "react": "^18.3.1",
@ -2727,6 +2728,15 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"dev": true, "dev": true,

View File

@ -18,6 +18,7 @@
"ef-ui": "file:", "ef-ui": "file:",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"mdb-react-ui-kit": "^8.0.0", "mdb-react-ui-kit": "^8.0.0",
"moment": "^2.30.1",
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^18.3.1", "react": "^18.3.1",

View File

@ -26,7 +26,7 @@ const Addproperty = () => {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
propertyTaxInfo: [ propertyTaxInfo: [
{ propertytaxowned: "", ownedyear: "", taxassessed: "", taxyear: "" }, { propertytaxowned: "0", ownedyear: "0", taxassessed: "0", taxyear: "0" },
], ],
images: [{ title: "", file: "" }], // Array to hold image objects images: [{ title: "", file: "" }], // Array to hold image objects
googleMapLink: "", // Field for Google Maps link googleMapLink: "", // Field for Google Maps link
@ -206,28 +206,32 @@ const Addproperty = () => {
}; };
const handlePriceChange = (e, index) => { const handlePriceChange = (e, index) => {
const value = e.target.value; let value = e.target.value;
// Use a regular expression to allow only numbers and decimals // Remove the dollar sign before validating
const isNumber = /^\d*\.?\d*$/.test(value); value = value.replace(/^\$/, '').trim(); // Remove '$' if it exists
// Use a regular expression to allow only numbers and decimals
const isNumber = /^\d*\.?\d*$/.test(value);
// If valid number, update state, otherwise show the alert
if (isNumber || value === "") {
const updatedCosts = formData.costPaidAtoB.map((cost, i) =>
i === index
? { ...cost, price: value, isInvalid: false } // Reset isInvalid if valid number
: cost
);
setFormData({ ...formData, costPaidAtoB: updatedCosts });
} else {
const updatedCosts = formData.costPaidAtoB.map((cost, i) =>
i === index
? { ...cost, isInvalid: true } // Keep isInvalid true for invalid input
: cost
);
setFormData({ ...formData, costPaidAtoB: updatedCosts });
}
};
// If valid number, update state, otherwise show the alert
if (isNumber || value === "") {
const updatedCosts = formData.costPaidAtoB.map((cost, i) =>
i === index
? { ...cost, price: value, isInvalid: false } // Reset isInvalid if valid number
: cost
);
setFormData({ ...formData, costPaidAtoB: updatedCosts });
} else {
const updatedCosts = formData.costPaidAtoB.map((cost, i) =>
i === index
? { ...cost, isInvalid: true } // Keep isInvalid true for invalid input
: cost
);
setFormData({ ...formData, costPaidAtoB: updatedCosts });
}
};
const calculateTotalPurchaseCosts = () => { const calculateTotalPurchaseCosts = () => {
const totalCostsFromArray = formData.costPaidAtoB.reduce((total, cost) => { const totalCostsFromArray = formData.costPaidAtoB.reduce((total, cost) => {
@ -268,6 +272,8 @@ const Addproperty = () => {
const handleCreditPriceChange = (e, index) => { const handleCreditPriceChange = (e, index) => {
const value = e.target.value; const value = e.target.value;
// Regular expression to allow only numbers and optional decimals // Regular expression to allow only numbers and optional decimals
const isNumber = /^\d*\.?\d*$/.test(value); const isNumber = /^\d*\.?\d*$/.test(value);
@ -839,6 +845,11 @@ const Addproperty = () => {
return NetProfitBeforeFinancingCosts - FinancingCostClosingCost; return NetProfitBeforeFinancingCosts - FinancingCostClosingCost;
}; };
const calculaterateofreturn =() => {
const rateofreturn = calculateNetProfit();
return rateofreturn;
}
const handleSubmit = () => { const handleSubmit = () => {
if ( if (
formData.address && formData.address &&
@ -880,6 +891,7 @@ const Addproperty = () => {
formData.LongTermRental && formData.LongTermRental &&
formData.FinancingCostClosingCost formData.FinancingCostClosingCost
) { ) {
const rateofreturn = calculaterateofreturn();
const totalPurchaseCosts = calculateTotalPurchaseCosts(); const totalPurchaseCosts = calculateTotalPurchaseCosts();
const totalPurchaseCostsaftercredits = const totalPurchaseCostsaftercredits =
calculateTotalPurchaseCostsWithCredits(); calculateTotalPurchaseCostsWithCredits();
@ -933,6 +945,7 @@ const Addproperty = () => {
netBtoCsalevalue: netBtoCsalevalue, netBtoCsalevalue: netBtoCsalevalue,
netprofitbeforefinancingcosts: netprofitbeforefinancingcosts, netprofitbeforefinancingcosts: netprofitbeforefinancingcosts,
NetProfit: NetProfit, NetProfit: NetProfit,
rateofreturn:rateofreturn
}; };
// Check if propertyTaxInfo is an array and has values // Check if propertyTaxInfo is an array and has values
@ -1924,9 +1937,26 @@ const Addproperty = () => {
required required
/> />
</div> </div>
<div>
<p><span style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}>[M-D-Y] </span>: <span style={{
color: "#000000",
fontSize: "14px",
fontWeight: "normal",
}}>{new Date(formData.closeDateAtoB).toLocaleDateString('en-US', {
month: 'numeric',
day: 'numeric',
year: 'numeric'
})}</span></p>
</div>
</div> </div>
<br />
<div className="row gy-3"> <div className="row gy-3">
{/* Close Date B to C */} {/* Close Date B to C */}
@ -1959,37 +1989,26 @@ const Addproperty = () => {
required required
/> />
</div> </div>
</div>
<br /> <div>
<p><span style={{
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417", color: "#fda417",
fontSize: "14px", fontSize: "14px",
fontWeight: "bold", fontWeight: "bold",
}} }}>[M-D-Y] : </span>
> <span style={{
Turn Time color: "#000000",
</span> fontSize: "14px",
<div className="col-md-4"> fontWeight: "normal",
<input }}>{new Date(formData.closeDateBtoC).toLocaleDateString('en-US', {
type="text" month: 'numeric',
className="form-control" day: 'numeric',
value={turnTime} year: 'numeric'
readOnly })}</span>
style={{
borderColor: "#fda417", // Custom border color for the input field </p>
color: "#fda417", // Optionally apply text color to the input text </div>
textAlign: "right",
}}
required
/>
</div>
</div> </div>
<br />
<div className="row gy-3 align-items-center"> <div className="row gy-3 align-items-center">
<span <span
@ -2031,15 +2050,7 @@ const Addproperty = () => {
))} ))}
</div> </div>
</div> </div>
<br />
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="row gy-3 align-items-center"> <div className="row gy-3 align-items-center">
<span <span
@ -2050,47 +2061,121 @@ const Addproperty = () => {
fontWeight: "bold", fontWeight: "bold",
}} }}
> >
Purchase Price Rate of Return
</span> </span>
<div className="col-md-4"> <div className="col-md-4">
<input <input
type="text" type="text"
className={`form-control ${formData.isPurchaseCostInvalid ? "is-invalid" : "" className="form-control"
}`} name="rateofreturn"
value={formData.purchaseCost} // value={calculaterateofreturn()}
name="purchaseCost" value={`$ ${calculaterateofreturn().toFixed(2)}`}
onChange={(e) => { readOnly
const value = e.target.value; style={{
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points borderColor: "#fda417", // Custom border color for the input field
setFormData({ color: "#fda417", // Optionally apply text color to the input text
...formData, textAlign: "right",
purchaseCost: value,
isPurchaseCostInvalid: !isValid, // Set isPurchaseCostInvalid to true if the value is not a valid number
});
}} }}
onKeyPress={(e) => {
const charCode = e.charCode;
// Allow only numbers and decimal points
if ((charCode < 48 || charCode > 57) && charCode !== 46) {
e.preventDefault(); // Prevent non-numeric input
setFormData({
...formData,
isPurchaseCostInvalid: true, // Set isPurchaseCostInvalid to true to show the alert
});
}
}}
placeholder="Enter Purchase Cost"
style={{ textAlign: "right" }}
required required
/> />
{formData.isPurchaseCostInvalid && (
<div className="invalid-feedback">
Please enter a valid number.
</div>
)}
</div> </div>
</div> </div>
<br />
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Turn Time
</span>
<div className="col-md-4">
<input
type="text"
className="form-control"
value={turnTime}
readOnly
style={{
borderColor: "#fda417", // Custom border color for the input field
color: "#fda417", // Optionally apply text color to the input text
textAlign: "right",
}}
required
/>
</div>
</div>
<br />
<hr
style={{
borderColor: "#fda417", // Set the color of the line
borderWidth: "1px", // Optional: Adjust the thickness of the line
backgroundColor: "#fda417", // Optional: Apply color if using for background
height: "1px", // Optional: Set height to match the border width
}}
/>
<div className="row gy-3 align-items-center">
<span
className="col-md-4"
style={{
color: "#fda417",
fontSize: "14px",
fontWeight: "bold",
}}
>
Purchase Price
</span>
<div className="col-md-4">
<input
type="text"
className={`form-control ${formData.isPurchaseCostInvalid ? "is-invalid" : ""}`}
value={`$ ${formData.purchaseCost}`} // Display the dollar sign in the input
name="purchaseCost"
onChange={(e) => {
let value = e.target.value.replace(/[^\d.]/g, ''); // Remove anything thats not a digit or decimal point
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
setFormData({
...formData,
purchaseCost: value,
isPurchaseCostInvalid: !isValid, // Set isPurchaseCostInvalid to true if the value is not a valid number
});
}}
onKeyPress={(e) => {
const charCode = e.charCode;
// Allow only numbers and decimal points
if ((charCode < 48 || charCode > 57) && charCode !== 46) {
e.preventDefault(); // Prevent non-numeric input
setFormData({
...formData,
isPurchaseCostInvalid: true, // Set isPurchaseCostInvalid to true to show the alert
});
}
}}
placeholder="Enter Purchase Cost"
style={{ textAlign: "right" }}
required
/>
{formData.isPurchaseCostInvalid && (
<div className="invalid-feedback">
Please enter a valid number.
</div>
)}
</div>
</div>
<hr <hr
style={{ style={{
borderColor: "#fda417", // Set the color of the line borderColor: "#fda417", // Set the color of the line
@ -2111,47 +2196,47 @@ const Addproperty = () => {
</span> </span>
{formData.costPaidAtoB.map((cost, index) => ( {formData.costPaidAtoB.map((cost, index) => (
<div key={index} className="row gy-3 align-items-center"> <div key={index} className="row gy-3 align-items-center">
<div className="col-md-4"> <div className="col-md-4">
<input <input
type="text" type="text"
className="form-control" className="form-control"
value={cost.title} value={cost.title}
onChange={(e) => onChange={(e) =>
handleCostChange(index, "title", e.target.value) handleCostChange(index, "title", e.target.value)
} }
placeholder="Title" placeholder="Title"
required required
/> />
</div> </div>
<div className="col-md-4"> <div className="col-md-4">
<input <input
type="text" type="text"
className={`form-control ${cost.isInvalid ? "is-invalid" : "" className={`form-control ${cost.isInvalid ? "is-invalid" : ""}`}
}`} // Apply 'is-invalid' class when invalid value={`$ ${cost.price}`}
value={cost.price} onChange={(e) => handlePriceChange(e, index)}
onChange={(e) => handlePriceChange(e, index)} // Use a new handler for price validation placeholder="Price"
placeholder="Price" style={{ textAlign: "right" }}
style={{ textAlign: "right" }} required
required />
/> {cost.isInvalid && (
{cost.isInvalid && ( <div className="invalid-feedback">
<div className="invalid-feedback"> Please enter a valid number.
Please enter a valid number. </div>
</div> )}
)} </div>
</div> <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={() => deleteCost(index)}
onClick={() => deleteCost(index)} style={{ marginLeft: "5px" }}
style={{ marginLeft: "5px" }} >
> x
x </button>
</button> </div>
</div> </div>
</div> ))}
))}
<div className="col-md-4"> <div className="col-md-4">
<button <button
@ -2183,20 +2268,21 @@ const Addproperty = () => {
Total Purchase Cost Total Purchase Cost
</span> </span>
<div className="col-md-4"> <div className="col-md-4">
<input <input
type="text" type="text"
className="form-control" className="form-control"
name="totalPurchaseCosts" name="totalPurchaseCosts"
value={calculateTotalPurchaseCosts()} value={`$ ${calculateTotalPurchaseCosts().toFixed(2)}`} // Add dollar sign before the calculated total and format it to 2 decimal places
readOnly readOnly
style={{ style={{
borderColor: "#fda417", // Custom border color for the input field borderColor: "#fda417", // Custom border color for the input field
color: "#fda417", // Optionally apply text color to the input text color: "#fda417", // Optionally apply text color to the input text
textAlign: "right", textAlign: "right",
}} }}
required required
/> />
</div> </div>
</div> </div>
<hr <hr
style={{ style={{
@ -2733,7 +2819,7 @@ const Addproperty = () => {
fontWeight: "bold", fontWeight: "bold",
}} }}
> >
Reno and Holding Costs Reno/Construction
</span> </span>
{formData.renovationCost.map((cost, index) => ( {formData.renovationCost.map((cost, index) => (
@ -2801,7 +2887,7 @@ const Addproperty = () => {
> >
+ +
</span>{" "} </span>{" "}
Add Renovation and Holding cost Add Reno/Construction
</button> </button>
</div> </div>