4119 lines
161 KiB
JavaScript
4119 lines
161 KiB
JavaScript
import { useState, useEffect } from "react";
|
||
import { useDispatch, useSelector } from "react-redux";
|
||
import { fetchPropertyById } from "../redux/features/propertySlice";
|
||
import { updateProperty } from "../redux/features/propertySlice";
|
||
import { useParams } from "react-router-dom";
|
||
import FileBase64 from "react-file-base64";
|
||
import Navbar from "./Navbar";
|
||
|
||
const EditProperty = () => {
|
||
const { id } = useParams();
|
||
const dispatch = useDispatch();
|
||
|
||
const [activeTab, setActiveTab] = useState("propertydetails");
|
||
const handleContinue = () => {
|
||
if (activeTab === "propertydetails") setActiveTab("Images");
|
||
if (activeTab === "Images") setActiveTab("Accounting");
|
||
};
|
||
|
||
const handleBack = () => {
|
||
if (activeTab === "Images") setActiveTab("propertydetails");
|
||
if (activeTab === "Accounting") setActiveTab("Images");
|
||
};
|
||
|
||
const { selectedProperty } = useSelector((state) => state.property);
|
||
|
||
const [formData, setFormData] = useState({
|
||
address: "",
|
||
city: "",
|
||
state: "",
|
||
zip: "",
|
||
propertyTaxInfo: [
|
||
{ propertytaxowned: "0", ownedyear: "0", taxassessed: "0", taxyear: "0" },
|
||
],
|
||
images: [{ title: "", file: "" }], // Array to hold image objects
|
||
googleMapLink: "", // Field for Google Maps link
|
||
purchaseCost: "0",
|
||
costPaidAtoB: [
|
||
{ title: "Closing Fees - Settlement Fee", price: "0" },
|
||
{ title: "Closing Fees - Owner's Title Insurance", price: "0" },
|
||
{ title: "Courier Fees", price: "0" },
|
||
{ title: "Wire Fee", price: "0" },
|
||
{ title: "E recording Fee", price: "0" },
|
||
{ title: "Recording Fee", price: "0" },
|
||
{ title: "Property Tax", price: "0" },
|
||
],
|
||
renovationRisk: null,
|
||
turnTime: "",
|
||
credits: [{ title: "Credits", price: "0" }],
|
||
cashAdjustments: [{ title: "Cash Adjustments", price: "0" }],
|
||
incidentalCost: [
|
||
{ title: "Accounting Fees", price: "0" },
|
||
{ title: "Bank Charges", price: "0" },
|
||
{ title: "Legal Fees", price: "0" },
|
||
{ title: "Property Taxes", price: "0" },
|
||
{ title: "Travel Expenses", price: "0" },
|
||
],
|
||
carryCosts: [
|
||
{ title: "Electricity", price: "0" },
|
||
{ title: "Water and Sewer", price: "0" },
|
||
{ title: "Natural Gas", price: "0" },
|
||
{ title: "Trash and Recycling", price: "0" },
|
||
{ title: "Internet and Cable", price: "0" },
|
||
{ title: "Heating Oil/Propane", price: "0" },
|
||
{ title: "HOA fees", price: "0" },
|
||
{ title: "Dump fees", price: "0" },
|
||
{ title: "Insurance", price: "0" },
|
||
{ title: "Interest on Loans", price: "0" },
|
||
{ title: "Loan Payment", price: "0" },
|
||
{ title: "Property Taxes", price: "0" },
|
||
{ title: "Security", price: "0" },
|
||
{ title: "Real Estates fees", price: "0" },
|
||
],
|
||
renovationCost: [
|
||
{
|
||
title: "Demolition: Removing existing structures or finishes",
|
||
price: "0",
|
||
},
|
||
{ title: "Framing: Making structural changes or additions", price: "0" },
|
||
{
|
||
title: "Plumbing: Installing or modifying plumbing systems",
|
||
price: "0",
|
||
},
|
||
{ title: "Electrical: Updating wiring and fixtures", price: "0" },
|
||
{
|
||
title: "HVAC: Installing or upgrading heating and cooling systems",
|
||
price: "0",
|
||
},
|
||
{ title: "Insulation: Adding or replacing insulation", price: "0" },
|
||
{ title: "Drywall: Hanging and finishing drywall", price: "0" },
|
||
{
|
||
title: "Interior Finishes: Painting, flooring, cabinetry, and fixtures",
|
||
price: "0",
|
||
},
|
||
{
|
||
title:
|
||
"Exterior Work: Addressing siding, roofing, or landscaping, if applicable",
|
||
price: "0",
|
||
},
|
||
{
|
||
title: "Final Inspections: Ensuring everything meets codes",
|
||
price: "0",
|
||
},
|
||
{ title: "Punch List: Completing any remaining task", price: "0" },
|
||
],
|
||
sellingPriceBtoC: "0",
|
||
costPaidOutofClosing: [
|
||
{ title: "Buyers Agent Commission", price: "0" },
|
||
{ title: "Sellers Agent Commission", price: "0" },
|
||
{ title: "Home Warranty", price: "0" },
|
||
{ title: "Document Preparation", price: "0" },
|
||
{ title: "Excise Tax", price: "0" },
|
||
{ title: "Legal Fees", price: "0" },
|
||
{ title: "Wire Fees/courier Fees", price: "0" },
|
||
{ title: "County Taxes", price: "0" },
|
||
{ title: "HOA Fee", price: "0" },
|
||
{ title: "Payoff of 1st Mortgage", price: "0" },
|
||
{ title: "Payoff of 2nd Mortgage", price: "0" },
|
||
{ title: "Payoff 3rd Mortgage", price: "0" },
|
||
],
|
||
adjustments: [{ title: "adjustments", price: "0" }],
|
||
incomestatement: [
|
||
{ title: "income statement", price: "0" },
|
||
{ title: "income statement", price: "0" },
|
||
],
|
||
fundspriortoclosing: "0",
|
||
shorttermrental: "0",
|
||
OtherIncome: "0",
|
||
InsuranceClaim: "0",
|
||
LongTermRental: "0",
|
||
FinancingCostClosingCost: "0",
|
||
});
|
||
|
||
const renovationRiskOptions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // Array of options
|
||
|
||
useEffect(() => {
|
||
dispatch(fetchPropertyById(id));
|
||
}, [dispatch, id]);
|
||
|
||
useEffect(() => {
|
||
if (selectedProperty) {
|
||
setFormData({
|
||
address: selectedProperty.address || "",
|
||
city: selectedProperty.city || "",
|
||
state: selectedProperty.state || "",
|
||
zip: selectedProperty.zip || "",
|
||
parcel: selectedProperty.parcel || "",
|
||
subdivision: selectedProperty.subdivision || "",
|
||
legal: selectedProperty.legal || "",
|
||
costpersqft: selectedProperty.costpersqft || "",
|
||
propertyType: selectedProperty.propertyType || "",
|
||
lotacres: selectedProperty.lotacres || "",
|
||
yearBuild: selectedProperty.yearBuild || "",
|
||
totallivingsqft: selectedProperty.totallivingsqft || "",
|
||
beds: selectedProperty.beds || "",
|
||
baths: selectedProperty.baths || "",
|
||
stories: selectedProperty.stories || "",
|
||
garage: selectedProperty.garage || "",
|
||
garagesqft: selectedProperty.garagesqft || "",
|
||
poolspa: selectedProperty.poolspa || "",
|
||
fireplaces: selectedProperty.fireplaces || "",
|
||
ac: selectedProperty.ac || "",
|
||
heating: selectedProperty.heating || "",
|
||
buildingstyle: selectedProperty.buildingstyle || "",
|
||
sitevacant: selectedProperty.sitevacant || "",
|
||
extwall: selectedProperty.extwall || "",
|
||
roofing: selectedProperty.roofing || "",
|
||
totalSqft: selectedProperty.totalSqft || "",
|
||
renovationRisk: selectedProperty.renovationRisk,
|
||
closeDateAtoB: selectedProperty.closeDateAtoB,
|
||
closeDateBtoC: selectedProperty.closeDateBtoC,
|
||
purchaseCost: selectedProperty.purchaseCost,
|
||
costPaidAtoB: selectedProperty.costPaidAtoB,
|
||
totalPurchaseCosts: selectedProperty.totalPurchaseCosts,
|
||
credits: selectedProperty.credits,
|
||
totalPurchaseCostsaftercredits:
|
||
selectedProperty.totalPurchaseCostsaftercredits,
|
||
cashAdjustments: selectedProperty.cashAdjustments,
|
||
totalcashrequiredonsettlement:
|
||
selectedProperty.totalcashrequiredonsettlement,
|
||
incidentalCost: selectedProperty.incidentalCost,
|
||
carryCosts: selectedProperty.carryCosts,
|
||
renovationCost: selectedProperty.renovationCost,
|
||
sellingPriceBtoC: selectedProperty.sellingPriceBtoC,
|
||
costPaidOutofClosing: selectedProperty.costPaidOutofClosing,
|
||
totalCosttoSellBtoC: selectedProperty.totalCosttoSellBtoC,
|
||
grossproceedsperHUD: selectedProperty.grossproceedsperHUD,
|
||
adjustments: selectedProperty.adjustments,
|
||
fundsavailablefordistribution:
|
||
selectedProperty.fundsavailablefordistribution,
|
||
incomestatement: selectedProperty.incomestatement,
|
||
fundspriortoclosing: selectedProperty.fundspriortoclosing,
|
||
shorttermrental: selectedProperty.shorttermrental,
|
||
OtherIncome: selectedProperty.OtherIncome,
|
||
InsuranceClaim: selectedProperty.InsuranceClaim,
|
||
LongTermRental: selectedProperty.LongTermRental,
|
||
netprofitbeforefinancingcosts:
|
||
selectedProperty.netprofitbeforefinancingcosts,
|
||
FinancingCostClosingCost: selectedProperty.FinancingCostClosingCost,
|
||
propertyTaxInfo: selectedProperty.propertyTaxInfo || [
|
||
{
|
||
propertytaxowned: "0",
|
||
ownedyear: "0",
|
||
taxassessed: "0",
|
||
taxyear: "0",
|
||
},
|
||
],
|
||
images: selectedProperty.images || [{ title: "", file: "" }],
|
||
googleMapLink: selectedProperty.googleMapLink,
|
||
rateofreturn: selectedProperty.rateofreturn,
|
||
});
|
||
}
|
||
}, [selectedProperty]);
|
||
|
||
const handleChange = (e) => {
|
||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||
};
|
||
|
||
// Handle specific changes for propertyTaxInfo array
|
||
const handleInputChange = (e, index) => {
|
||
const { name, value } = e.target;
|
||
|
||
// Make a shallow copy of the propertyTaxInfo array
|
||
const updatedPropertyTaxInfo = [...formData.propertyTaxInfo];
|
||
|
||
// Make a shallow copy of the object you want to modify (taxInfo at index)
|
||
const updatedTaxInfo = { ...updatedPropertyTaxInfo[index] };
|
||
|
||
// Update the field in the copied object
|
||
updatedTaxInfo[name] = value;
|
||
|
||
// Replace the old object with the updated one in the array
|
||
updatedPropertyTaxInfo[index] = updatedTaxInfo;
|
||
|
||
// Finally, update the formData with the updated propertyTaxInfo array
|
||
setFormData({ ...formData, propertyTaxInfo: updatedPropertyTaxInfo });
|
||
};
|
||
|
||
// const handleSubmit = (e) => {
|
||
// e.preventDefault();
|
||
// dispatch(updateProperty({ id, propertyData: formData }));
|
||
// };
|
||
|
||
const handleSubmit = (e) => {
|
||
e.preventDefault();
|
||
|
||
// Calculate total purchase costs and update the formData
|
||
const totalPurchaseCosts = calculateTotalPurchaseCosts();
|
||
const totalcredits = calculateTotalCredits();
|
||
const totalPurchaseCostsaftercredits =
|
||
calculateTotalPurchaseCostsWithCredits();
|
||
const totalcashAdjustments = calculatecashAdjustments();
|
||
const totalcashrequiredonsettlement =
|
||
calculateTotalCashRequiredonSettlement();
|
||
const totalincidentalCost = calculateTotalincidentalCost();
|
||
const totalcarryCosts = calculatetotalcarryCosts();
|
||
const totalrenovationCost = calculaterenovationCost();
|
||
const totalRenovationsandHoldingCost =
|
||
calculatetotalRenovationsandHoldingCost();
|
||
const totalCoststoBuyAtoB = calculatetotalCoststoBuyAtoB();
|
||
const totalcostPaidOutofClosing = calculateTotalcostPaidOutofClosing();
|
||
const totalCosttoSellBtoC = calculateTotalCosttoSellBtoC();
|
||
const grossproceedsperHUD = calculateTotalCosttoSellBtoC();
|
||
const totaladjustments = calculateTotaladjustments();
|
||
const fundsavailablefordistribution =
|
||
calculatefundsavailablefordistribution();
|
||
const totalincomestatement = calculateTotalincomestatement();
|
||
const netBtoCsalevalue = calculatenetBtoCsalevalue();
|
||
const netprofitbeforefinancingcosts =
|
||
calculateNetProfitBeforeFinancingCosts();
|
||
const netprofit = calculateNetProfit();
|
||
|
||
// Update the formData with the calculated total purchase cost
|
||
const updatedFormData = {
|
||
...formData,
|
||
totalPurchaseCosts: totalPurchaseCosts.toFixed(2), // Store as a string with 2 decimal places
|
||
totalcredits: totalcredits.toFixed(2),
|
||
totalPurchaseCostsaftercredits: totalPurchaseCostsaftercredits.toFixed(2),
|
||
totalcashAdjustments: totalcashAdjustments.toFixed(2),
|
||
totalcashrequiredonsettlement: totalcashrequiredonsettlement.toFixed(2),
|
||
totalincidentalCost: totalincidentalCost.toFixed(2),
|
||
totalcarryCosts: totalcarryCosts.toFixed(2),
|
||
totalrenovationCost: totalrenovationCost.toFixed(2),
|
||
totalRenovationsandHoldingCost: totalRenovationsandHoldingCost.toFixed(2),
|
||
totalCoststoBuyAtoB: totalCoststoBuyAtoB.toFixed(2),
|
||
totalcostPaidOutofClosing: totalcostPaidOutofClosing.toFixed(2),
|
||
totalCosttoSellBtoC: totalCosttoSellBtoC.toFixed(2),
|
||
grossproceedsperHUD: grossproceedsperHUD.toFixed(2),
|
||
totaladjustments: totaladjustments.toFixed(2),
|
||
fundsavailablefordistribution: fundsavailablefordistribution.toFixed(2),
|
||
totalincomestatement: totalincomestatement.toFixed(2),
|
||
netBtoCsalevalue: netBtoCsalevalue.toFixed(2),
|
||
netprofitbeforefinancingcosts: netprofitbeforefinancingcosts.toFixed(2),
|
||
netprofit: netprofit.toFixed(2),
|
||
};
|
||
|
||
// Dispatch the updated formData
|
||
dispatch(updateProperty({ id, propertyData: updatedFormData }));
|
||
};
|
||
|
||
const addPropertyTaxField = () => {
|
||
setFormData({
|
||
...formData,
|
||
propertyTaxInfo: [
|
||
...formData.propertyTaxInfo,
|
||
{ propertytaxowned: "", ownedyear: "", taxassessed: "", taxyear: "" },
|
||
],
|
||
});
|
||
};
|
||
|
||
const deletePropertyTaxField = (index) => {
|
||
const updatedPropertyTaxInfo = formData.propertyTaxInfo.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData({ ...formData, propertyTaxInfo: updatedPropertyTaxInfo });
|
||
};
|
||
|
||
const handleImageChange = (file, index) => {
|
||
const updatedImages = [...formData.images];
|
||
updatedImages[index] = {
|
||
...updatedImages[index],
|
||
file: file.base64, // Store the base64 format of the image
|
||
};
|
||
|
||
setFormData({ ...formData, images: updatedImages });
|
||
};
|
||
|
||
const handleAddImage = () => {
|
||
setFormData({
|
||
...formData,
|
||
images: [...formData.images, { title: "", file: "" }],
|
||
});
|
||
};
|
||
|
||
const handleDeleteImage = (index) => {
|
||
const updatedImages = formData.images.filter((_, i) => i !== index);
|
||
setFormData({ ...formData, images: updatedImages });
|
||
};
|
||
|
||
const handleImageTitleChange = (index, e) => {
|
||
const updatedImages = [...formData.images];
|
||
updatedImages[index] = {
|
||
...updatedImages[index],
|
||
title: e.target.value,
|
||
};
|
||
|
||
setFormData({ ...formData, images: updatedImages });
|
||
};
|
||
|
||
useEffect(() => {
|
||
calculateTurnTime(formData.closeDateAtoB, formData.closeDateBtoC);
|
||
}, [formData.closeDateAtoB, formData.closeDateBtoC]);
|
||
|
||
const [turnTime, setTurnTime] = useState("0 days"); // Store the calculated turn time
|
||
|
||
const calculateTurnTime = (closeDateAtoB, closeDateBtoC) => {
|
||
if (closeDateAtoB && closeDateBtoC) {
|
||
const dateA = new Date(closeDateAtoB);
|
||
const dateB = new Date(closeDateBtoC);
|
||
|
||
// Calculate difference in time
|
||
const diffTime = Math.abs(dateB - dateA);
|
||
|
||
// Calculate difference in days
|
||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||
|
||
// Update state with the calculated turn time
|
||
// setTurnTime(diffDays);
|
||
setTurnTime(`${diffDays} days`);
|
||
} else {
|
||
setTurnTime("0 days"); // Reset if dates are not available
|
||
}
|
||
};
|
||
|
||
const addCost = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidAtoB: [...prevData.costPaidAtoB, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteCost = (index) => {
|
||
const updatedCosts = formData.costPaidAtoB.filter((_, i) => i !== index);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidAtoB: updatedCosts,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to title and price
|
||
const handleCostChange = (index, field, value) => {
|
||
const updatedCosts = [...formData.costPaidAtoB];
|
||
updatedCosts[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidAtoB: updatedCosts,
|
||
}));
|
||
};
|
||
|
||
const handlePriceChange = (e, index) => {
|
||
let value = e.target.value;
|
||
|
||
// Remove the dollar sign before validating
|
||
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 });
|
||
}
|
||
};
|
||
|
||
const calculateTotalPurchaseCosts = () => {
|
||
const totalCostsFromArray = formData.costPaidAtoB.reduce((total, cost) => {
|
||
const price = parseFloat(cost.price) || 0; // Convert price to number
|
||
return total + price;
|
||
}, 0);
|
||
|
||
const purchaseCost = parseFloat(formData.purchaseCost) || 0; // Convert purchase cost to number
|
||
|
||
return totalCostsFromArray + purchaseCost; // Return the total
|
||
};
|
||
|
||
const addCredits = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
credits: [...prevData.credits, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteCredits = (index) => {
|
||
const updatedCredits = formData.credits.filter((_, i) => i !== index);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
credits: updatedCredits,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to credits title and price
|
||
const handleCreditChange = (index, field, value) => {
|
||
const updatedCredits = [...formData.credits];
|
||
updatedCredits[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
credits: updatedCredits,
|
||
}));
|
||
};
|
||
|
||
const handleCreditPriceChange = (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 updatedCredits = formData.credits.map((credit, i) =>
|
||
i === index
|
||
? { ...credit, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: credit
|
||
);
|
||
setFormData({ ...formData, credits: updatedCredits });
|
||
} else {
|
||
const updatedCredits = formData.credits.map((credit, i) =>
|
||
i === index
|
||
? { ...credit, isInvalid: true } // Set isInvalid true for invalid input
|
||
: credit
|
||
);
|
||
setFormData({ ...formData, credits: updatedCredits });
|
||
}
|
||
};
|
||
|
||
const calculateTotalCredits = () => {
|
||
return formData.credits.reduce((total, credits) => {
|
||
const price = parseFloat(credits.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const calculateTotalPurchaseCostsWithCredits = () => {
|
||
// Calculate total from costPaidAtoB array
|
||
const totalCostsFromArray = formData.costPaidAtoB.reduce((total, cost) => {
|
||
const price = parseFloat(cost.price) || 0; // Convert price to number
|
||
return total + price;
|
||
}, 0);
|
||
|
||
// Calculate total from credits array
|
||
const totalCreditsFromArray = formData.credits.reduce((total, credit) => {
|
||
const price = parseFloat(credit.price) || 0; // Convert price to number
|
||
return total + price;
|
||
}, 0);
|
||
|
||
// Convert purchase cost to number
|
||
const purchaseCost = parseFloat(formData.purchaseCost) || 0;
|
||
return totalCostsFromArray + totalCreditsFromArray + purchaseCost;
|
||
};
|
||
|
||
const addcashAdjustments = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
cashAdjustments: [...prevData.cashAdjustments, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deletecashAdjustments = (index) => {
|
||
const updatedcashAdjustments = formData.cashAdjustments.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
cashAdjustments: updatedcashAdjustments,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to cashAdjustments title and price
|
||
const handlecashAdjustmentsTitle = (index, field, value) => {
|
||
const updatedcashAdjustments = [...formData.cashAdjustments];
|
||
updatedcashAdjustments[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
cashAdjustments: updatedcashAdjustments,
|
||
}));
|
||
};
|
||
|
||
const handlecashAdjustmentsCostChange = (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 updatedcashAdjustments = formData.cashAdjustments.map(
|
||
(cashAdjustments, i) =>
|
||
i === index
|
||
? { ...cashAdjustments, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: cashAdjustments
|
||
);
|
||
setFormData({ ...formData, cashAdjustments: updatedcashAdjustments });
|
||
} else {
|
||
const updatedcashAdjustments = formData.cashAdjustments.map(
|
||
(cashAdjustments, i) =>
|
||
i === index
|
||
? { ...cashAdjustments, isInvalid: true } // Set isInvalid true for invalid input
|
||
: cashAdjustments
|
||
);
|
||
setFormData({ ...formData, cashAdjustments: updatedcashAdjustments });
|
||
}
|
||
};
|
||
|
||
// Calculate total from cash Adjustments array
|
||
const calculatecashAdjustments = () => {
|
||
return formData.cashAdjustments.reduce((total, cashAdjustments) => {
|
||
const price = parseFloat(cashAdjustments.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const calculateTotalCashRequiredonSettlement = () => {
|
||
const totalcashAdjustments = calculatecashAdjustments();
|
||
const totalcredits = calculateTotalCredits();
|
||
const totalPurchaseCosts = calculateTotalPurchaseCosts();
|
||
|
||
// Sum up all the values from the three functions
|
||
return totalcashAdjustments + totalcredits + totalPurchaseCosts;
|
||
};
|
||
|
||
const addincidentalCost = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incidentalCost: [...prevData.incidentalCost, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteincidentalCost = (index) => {
|
||
const updatedincidentalCost = formData.incidentalCost.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incidentalCost: updatedincidentalCost,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handleincidentalCostTitle = (index, field, value) => {
|
||
const updatedincidentalCost = [...formData.incidentalCost];
|
||
updatedincidentalCost[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incidentalCost: updatedincidentalCost,
|
||
}));
|
||
};
|
||
|
||
const handleincidentalCostChange = (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 updatedincidentalCost = formData.incidentalCost.map(
|
||
(incidentalCost, i) =>
|
||
i === index
|
||
? { ...incidentalCost, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: incidentalCost
|
||
);
|
||
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
||
} else {
|
||
const updatedincidentalCost = formData.incidentalCost.map(
|
||
(incidentalCost, i) =>
|
||
i === index
|
||
? { ...incidentalCost, isInvalid: true } // Set isInvalid true for invalid input
|
||
: incidentalCost
|
||
);
|
||
setFormData({ ...formData, incidentalCost: updatedincidentalCost });
|
||
}
|
||
};
|
||
|
||
// Calculate total from incidentalCost array
|
||
const calculateTotalincidentalCost = () => {
|
||
return formData.incidentalCost.reduce((total, incidentalCost) => {
|
||
const price = parseFloat(incidentalCost.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const addcarryCosts = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
carryCosts: [...prevData.carryCosts, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deletecarryCosts = (index) => {
|
||
const updatedcarryCosts = formData.carryCosts.filter((_, i) => i !== index);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
carryCosts: updatedcarryCosts,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handlecarryCostsTitle = (index, field, value) => {
|
||
const updatedcarryCosts = [...formData.carryCosts];
|
||
updatedcarryCosts[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
carryCosts: updatedcarryCosts,
|
||
}));
|
||
};
|
||
|
||
const handlecarryCostsChange = (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 updatedcarryCosts = formData.carryCosts.map((carryCosts, i) =>
|
||
i === index
|
||
? { ...carryCosts, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: carryCosts
|
||
);
|
||
setFormData({ ...formData, carryCosts: updatedcarryCosts });
|
||
} else {
|
||
const updatedcarryCosts = formData.carryCosts.map((carryCosts, i) =>
|
||
i === index
|
||
? { ...carryCosts, isInvalid: true } // Set isInvalid true for invalid input
|
||
: carryCosts
|
||
);
|
||
setFormData({ ...formData, carryCosts: updatedcarryCosts });
|
||
}
|
||
};
|
||
|
||
// Calculate total from incidentalCost array
|
||
const calculatetotalcarryCosts = () => {
|
||
return formData.carryCosts.reduce((total, carryCosts) => {
|
||
const price = parseFloat(carryCosts.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const addrenovationCost = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
renovationCost: [...prevData.renovationCost, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleterenovationCost = (index) => {
|
||
const updatedrenovationCost = formData.renovationCost.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
renovationCost: updatedrenovationCost,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to renovation Cost title and price
|
||
const handlerenovationCostTitle = (index, field, value) => {
|
||
const updatedrenovationCost = [...formData.renovationCost];
|
||
updatedrenovationCost[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
renovationCost: updatedrenovationCost,
|
||
}));
|
||
};
|
||
|
||
const handlerenovationCostChange = (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 updatedrenovationCost = formData.renovationCost.map(
|
||
(renovationCost, i) =>
|
||
i === index
|
||
? { ...renovationCost, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: renovationCost
|
||
);
|
||
setFormData({ ...formData, renovationCost: updatedrenovationCost });
|
||
} else {
|
||
const updatedrenovationCost = formData.renovationCost.map(
|
||
(renovationCost, i) =>
|
||
i === index
|
||
? { ...renovationCost, isInvalid: true } // Set isInvalid true for invalid input
|
||
: renovationCost
|
||
);
|
||
setFormData({ ...formData, renovationCost: updatedrenovationCost });
|
||
}
|
||
};
|
||
|
||
// Calculate total from incidentalCost array
|
||
const calculaterenovationCost = () => {
|
||
return formData.renovationCost.reduce((total, renovationCost) => {
|
||
const price = parseFloat(renovationCost.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const calculatetotalRenovationsandHoldingCost = () => {
|
||
const totalIncidentalCost = calculateTotalincidentalCost();
|
||
const totalcarryCosts = calculatetotalcarryCosts();
|
||
const totalRenovationCost = calculaterenovationCost();
|
||
|
||
// Sum up all the values from the three functions
|
||
return totalIncidentalCost + totalcarryCosts + totalRenovationCost;
|
||
};
|
||
|
||
const calculatetotalCoststoBuyAtoB = () => {
|
||
const totalRenovationsandHoldingCost =
|
||
calculatetotalRenovationsandHoldingCost();
|
||
const totalCashRequiredonSettlement =
|
||
calculateTotalCashRequiredonSettlement();
|
||
|
||
// Sum up all the values from the three functions
|
||
return totalRenovationsandHoldingCost + totalCashRequiredonSettlement;
|
||
};
|
||
|
||
const addcostPaidOutofClosing = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidOutofClosing: [
|
||
...prevData.costPaidOutofClosing,
|
||
{ title: "", price: "" },
|
||
],
|
||
}));
|
||
};
|
||
|
||
const deletecostPaidOutofClosing = (index) => {
|
||
const updatedcostPaidOutofClosing = formData.costPaidOutofClosing.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidOutofClosing: updatedcostPaidOutofClosing,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handlecostPaidOutofClosingTitle = (index, field, value) => {
|
||
const updatedcostPaidOutofClosing = [...formData.costPaidOutofClosing];
|
||
updatedcostPaidOutofClosing[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
costPaidOutofClosing: updatedcostPaidOutofClosing,
|
||
}));
|
||
};
|
||
|
||
const handlecostPaidOutofClosingChange = (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 updatedcostPaidOutofClosing = formData.costPaidOutofClosing.map(
|
||
(costPaidOutofClosing, i) =>
|
||
i === index
|
||
? { ...costPaidOutofClosing, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: costPaidOutofClosing
|
||
);
|
||
setFormData({
|
||
...formData,
|
||
costPaidOutofClosing: updatedcostPaidOutofClosing,
|
||
});
|
||
} else {
|
||
const updatedcostPaidOutofClosing = formData.costPaidOutofClosing.map(
|
||
(costPaidOutofClosing, i) =>
|
||
i === index
|
||
? { ...costPaidOutofClosing, isInvalid: true } // Set isInvalid true for invalid input
|
||
: costPaidOutofClosing
|
||
);
|
||
setFormData({
|
||
...formData,
|
||
costPaidOutofClosing: updatedcostPaidOutofClosing,
|
||
});
|
||
}
|
||
};
|
||
|
||
// Calculate total from costPaidOutofClosing array
|
||
const calculateTotalcostPaidOutofClosing = () => {
|
||
return formData.costPaidOutofClosing.reduce(
|
||
(total, costPaidOutofClosing) => {
|
||
const price = parseFloat(costPaidOutofClosing.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
},
|
||
0
|
||
);
|
||
};
|
||
|
||
const calculateTotalCosttoSellBtoC = () => {
|
||
const sekkingPriceBtoC = formData.sellingPriceBtoC;
|
||
const costPaidOutofClosing = calculateTotalcostPaidOutofClosing();
|
||
return sekkingPriceBtoC - costPaidOutofClosing;
|
||
};
|
||
|
||
const addadjustments = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
adjustments: [...prevData.adjustments, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteadjustments = (index) => {
|
||
const updatedadjustments = formData.adjustments.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
adjustments: updatedadjustments,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handleadjustmentsTitle = (index, field, value) => {
|
||
const updatedadjustments = [...formData.adjustments];
|
||
updatedadjustments[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
adjustments: updatedadjustments,
|
||
}));
|
||
};
|
||
|
||
const handleadjustmentsChange = (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 updatedadjustments = formData.adjustments.map((adjustments, i) =>
|
||
i === index
|
||
? { ...adjustments, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: adjustments
|
||
);
|
||
setFormData({ ...formData, adjustments: updatedadjustments });
|
||
} else {
|
||
const updatedadjustments = formData.adjustments.map((adjustments, i) =>
|
||
i === index
|
||
? { ...adjustments, isInvalid: true } // Set isInvalid true for invalid input
|
||
: adjustments
|
||
);
|
||
setFormData({ ...formData, adjustments: updatedadjustments });
|
||
}
|
||
};
|
||
|
||
// Calculate total from incidentalCost array
|
||
const calculateTotaladjustments = () => {
|
||
return formData.adjustments.reduce((total, adjustments) => {
|
||
const price = parseFloat(adjustments.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const calculatefundsavailablefordistribution = () => {
|
||
const sellingPriceBtoC = calculateTotalCosttoSellBtoC();
|
||
const totaladjustments = calculateTotaladjustments();
|
||
return sellingPriceBtoC + totaladjustments;
|
||
};
|
||
|
||
const addincomestatement = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incomestatement: [...prevData.incomestatement, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteincomestatement = (index) => {
|
||
const updatedincomestatement = formData.incomestatement.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incomestatement: updatedincomestatement,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handleincomestatementTitle = (index, field, value) => {
|
||
const updatedincomestatement = [...formData.incomestatement];
|
||
updatedincomestatement[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
incomestatement: updatedincomestatement,
|
||
}));
|
||
};
|
||
|
||
const handleincomestatementChange = (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 updatedincomestatement = formData.incomestatement.map(
|
||
(incomestatement, i) =>
|
||
i === index
|
||
? { ...incomestatement, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: incomestatement
|
||
);
|
||
setFormData({ ...formData, incomestatement: updatedincomestatement });
|
||
} else {
|
||
const updatedincomestatement = formData.incomestatement.map(
|
||
(incomestatement, i) =>
|
||
i === index
|
||
? { ...incomestatement, isInvalid: true } // Set isInvalid true for invalid input
|
||
: incomestatement
|
||
);
|
||
setFormData({ ...formData, incomestatement: updatedincomestatement });
|
||
}
|
||
};
|
||
|
||
// Calculate total from incidentalCost array
|
||
const calculateTotalincomestatement = () => {
|
||
return formData.incomestatement.reduce((total, incomestatement) => {
|
||
const price = parseFloat(incomestatement.price);
|
||
return total + (isNaN(price) ? 0 : price); // Ensure only valid numbers are added
|
||
}, 0);
|
||
};
|
||
|
||
const calculatenetBtoCsalevalue = () => {
|
||
const totalincomestatement = calculateTotalincomestatement();
|
||
const totalcosttosellbtoc = calculateTotalCosttoSellBtoC();
|
||
return totalincomestatement + totalcosttosellbtoc;
|
||
};
|
||
|
||
const calculateNetProfitBeforeFinancingCosts = () => {
|
||
// const netBtoCsalevalue = parseFloat(calculatenetBtoCsalevalue());
|
||
// const shorttermrental = parseFloat(formData.shorttermrental);
|
||
// const OtherIncome = parseFloat(formData.OtherIncome);
|
||
// const InsuranceClaim = parseFloat(formData.InsuranceClaim);
|
||
// const LongTermRental = parseFloat(formData.LongTermRental);
|
||
// const totalCoststoBuyAtoB = parseFloat(calculatetotalCoststoBuyAtoB());
|
||
const netBtoCsalevalue = isNaN(parseFloat(calculatenetBtoCsalevalue()))
|
||
? 0
|
||
: parseFloat(calculatenetBtoCsalevalue());
|
||
const shorttermrental = isNaN(parseFloat(formData.shorttermrental))
|
||
? 0
|
||
: parseFloat(formData.shorttermrental);
|
||
const OtherIncome = isNaN(parseFloat(formData.OtherIncome))
|
||
? 0
|
||
: parseFloat(formData.OtherIncome);
|
||
const InsuranceClaim = isNaN(parseFloat(formData.InsuranceClaim))
|
||
? 0
|
||
: parseFloat(formData.InsuranceClaim);
|
||
const LongTermRental = isNaN(parseFloat(formData.LongTermRental))
|
||
? 0
|
||
: parseFloat(formData.LongTermRental);
|
||
const totalCoststoBuyAtoB = isNaN(
|
||
parseFloat(calculatetotalCoststoBuyAtoB())
|
||
)
|
||
? 0
|
||
: parseFloat(calculatetotalCoststoBuyAtoB());
|
||
|
||
// Calculate the sum first, then subtract the total costs
|
||
const totalIncome =
|
||
netBtoCsalevalue +
|
||
shorttermrental +
|
||
OtherIncome +
|
||
InsuranceClaim +
|
||
LongTermRental;
|
||
const netProfitBeforeFinancingCosts = totalIncome - totalCoststoBuyAtoB;
|
||
return netProfitBeforeFinancingCosts;
|
||
};
|
||
|
||
const calculateNetProfit = () => {
|
||
const NetProfitBeforeFinancingCosts =
|
||
calculateNetProfitBeforeFinancingCosts();
|
||
const FinancingCostClosingCost = formData.FinancingCostClosingCost;
|
||
return NetProfitBeforeFinancingCosts - FinancingCostClosingCost;
|
||
};
|
||
|
||
const calculaterateofreturn = () => {
|
||
const rateofreturn = calculateNetProfit();
|
||
return rateofreturn;
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Navbar />
|
||
<br /> <br /> <br /> <br /> <br /> <br />
|
||
<div className="card d-flex justify-content-center align-items-center">
|
||
<div className="justify-content-center">
|
||
<ul className="nav nav-tabs" role="tablist">
|
||
<li
|
||
role="presentation"
|
||
className={activeTab === "propertydetails" ? "active tab" : "tab"}
|
||
>
|
||
<a onClick={() => setActiveTab("propertydetails")} role="tab">
|
||
Property Details
|
||
</a>
|
||
</li>
|
||
<li
|
||
role="presentation"
|
||
className={activeTab === "Images" ? "active tab" : "tab"}
|
||
>
|
||
<a onClick={() => setActiveTab("Images")} role="tab">
|
||
Images, Maps
|
||
</a>
|
||
</li>
|
||
|
||
<li
|
||
role="presentation"
|
||
className={activeTab === "Accounting" ? "active tab" : "tab"}
|
||
>
|
||
<a onClick={() => setActiveTab("Accounting")} role="tab">
|
||
Accounting
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
<div className="tab-content">
|
||
{activeTab === "propertydetails" && (
|
||
<div role="tabpanel" className="card tab-pane active">
|
||
<form>
|
||
<h3
|
||
style={{
|
||
color: "#fda417",
|
||
border: "#fda417",
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
Property Location
|
||
</h3>
|
||
<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">
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Property Address
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="address"
|
||
value={formData.address}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
City
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="city"
|
||
value={formData.city}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
State
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="state"
|
||
value={formData.state}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="Alaska">Alaska</option>
|
||
<option value="Alabama">Alabama</option>
|
||
<option value="Arkansas">Arkansas</option>
|
||
<option value="Arizona">Arizona</option>
|
||
<option value="California">California</option>
|
||
<option value="Colorado">Colorado</option>
|
||
<option value="Connecticut">Connecticut</option>
|
||
<option value="District Of Columbia">
|
||
District Of Columbia
|
||
</option>
|
||
<option value="Delaware">Delaware</option>
|
||
<option value="Florida">Florida</option>
|
||
<option value="Georgia">Georgia</option>
|
||
<option value="Hawaii">Hawaii</option>
|
||
<option value="Iowa">Iowa</option>
|
||
<option value="Idaho">Idaho</option>
|
||
<option value="Illinois">Illinois</option>
|
||
<option value="Indiana">Indiana</option>
|
||
<option value="Kansas">Kansas</option>
|
||
<option value="Kentucky">Kentucky</option>
|
||
<option value="Louisiana">Louisiana</option>
|
||
<option value="Massachusetts">Massachusetts</option>
|
||
<option value="Maryland">Maryland</option>
|
||
<option value="Michigan">Michigan</option>
|
||
<option value="Minnesota">Minnesota</option>
|
||
<option value="Missouri">Missouri</option>
|
||
<option value="Mississippi">Mississippi</option>
|
||
<option value="Montana">Montana</option>
|
||
<option value="North Carolina">North Carolina</option>
|
||
<option value="North Dakota">North Dakota</option>
|
||
<option value="Nebraska">Nebraska</option>
|
||
<option value="New Hampshire">New Hampshire</option>
|
||
<option value="New Jersey">New Jersey</option>
|
||
<option value="New Mexico">New Mexico</option>
|
||
<option value="Nevada">Nevada</option>
|
||
<option value="New York">New York</option>
|
||
<option value="Ohio">Ohio</option>
|
||
<option value="Oklahoma">Oklahoma</option>
|
||
<option value="Oregon">Oregon</option>
|
||
<option value="Pennsylvania">Pennsylvania</option>
|
||
<option value="Rhode Island">Rhode Island</option>
|
||
<option value="South Carolina">South Carolina</option>
|
||
<option value="South Dakota">South Dakota</option>
|
||
<option value="Tennessee">Tennessee</option>
|
||
<option value="Texas">Texas</option>
|
||
<option value="Texas">Travis</option>
|
||
<option value="Utah">Utah</option>
|
||
<option value="Virginia">Virginia</option>
|
||
<option value="Vermont">Vermont</option>
|
||
<option value="Washington">Washington</option>
|
||
<option value="Wisconsin">Wisconsin</option>
|
||
<option value="West Virginia">West Virginia</option>
|
||
<option value="Wyoming">Wyoming</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
County
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="county"
|
||
value={formData.county}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="Abbeville">Abbeville</option>
|
||
<option value="Aiken">Aiken</option>
|
||
<option value="Allendale">Allendale</option>
|
||
<option value="Anderson">Anderson</option>
|
||
<option value="Bamberg">Bamberg</option>
|
||
<option value="Barnwell">Barnwell</option>
|
||
<option value="Beaufort">Beaufort</option>
|
||
<option value="Berkeley">Berkeley</option>
|
||
<option value="Calhoun">Calhoun</option>
|
||
<option value="Charleston">Charleston</option>
|
||
<option value="Cherokee">Cherokee</option>
|
||
<option value="Chester">Chester</option>
|
||
<option value="Chesterfield">Chesterfield</option>
|
||
<option value="Clarendon">Clarendon</option>
|
||
<option value="Colleton">Colleton</option>
|
||
<option value="Darlington">Darlington</option>
|
||
<option value="Dillon">Dillon</option>
|
||
<option value="Dorchester">Dorchester</option>
|
||
<option value="Edgefield">Edgefield</option>
|
||
<option value="Fairfield">Fairfield</option>
|
||
<option value="Florence">Florence</option>
|
||
<option value="Georgetown">Georgetown</option>
|
||
<option value="Greenville">Greenville</option>
|
||
<option value="Greenwood">Greenwood</option>
|
||
<option value="Hampton">Hampton</option>
|
||
<option value="Horry">Horry</option>
|
||
<option value="Jasper">Jasper</option>
|
||
<option value="Kershaw">Kershaw</option>
|
||
<option value="Lancaster">Lancaster</option>
|
||
<option value="Laurens">Laurens</option>
|
||
<option value="Lee">Lee</option>
|
||
<option value="Lexington">Lexington</option>
|
||
<option value="Marion">Marion</option>
|
||
<option value="Marlboro">Marlboro</option>
|
||
<option value="McCormick">McCormick</option>
|
||
<option value="Newberry">Newberry</option>
|
||
<option value="Oconee">Oconee</option>
|
||
<option value="Orangeburg">Orangeburg</option>
|
||
<option value="Pickens">Pickens</option>
|
||
<option value="Richland">Richland</option>
|
||
<option value="Saluda">Saluda</option>
|
||
<option value="Spartanburg">Spartanburg</option>
|
||
<option value="Sumter">Sumter</option>
|
||
<option value="Union">Union</option>
|
||
<option value="Williamsburg">Williamsburg</option>
|
||
<option value="York">York</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Zip
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="zip"
|
||
value={formData.zip}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Parcel
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="parcel"
|
||
value={formData.parcel}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Sub division
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="subdivision"
|
||
value={formData.subdivision}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Legal Description
|
||
<textarea
|
||
type="text"
|
||
className="form-control"
|
||
name="legal"
|
||
value={formData.legal}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Cost per SQFT
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="costpersqft"
|
||
value={formData.costpersqft}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
Property Type
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="propertyType"
|
||
value={formData.propertyType}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="Residential">Residential</option>
|
||
<option value="Land">Land</option>
|
||
<option value="Commercial">Commercial</option>
|
||
<option value="Industrial">Industrial</option>
|
||
<option value="Water">Water</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Lot Acres/Sqft
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="lotacres"
|
||
value={formData.lotacres}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Year Build
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="yearBuild"
|
||
value={formData.yearBuild}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Total Living SQFT
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totallivingsqft"
|
||
value={formData.totallivingsqft}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Beds
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="beds"
|
||
value={formData.beds}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Baths
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="baths"
|
||
value={formData.baths}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
Stories
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="stories"
|
||
value={formData.stories}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="0">0</option>
|
||
<option value="1">1</option>
|
||
<option value="2">2</option>
|
||
<option value="3">3</option>
|
||
<option value="4">4</option>
|
||
<option value="5">5</option>
|
||
<option value="6">6</option>
|
||
<option value="7">7</option>
|
||
<option value="8">8</option>
|
||
<option value="9">9</option>
|
||
<option value="10">10</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
Garage
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="garage"
|
||
value={formData.garage}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="0">0</option>
|
||
<option value="1">1</option>
|
||
<option value="2">2</option>
|
||
<option value="3">3</option>
|
||
<option value="4">4</option>
|
||
<option value="5">5</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Garage SQFT
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="garagesqft"
|
||
value={formData.garagesqft}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
Pool/SPA
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="poolspa"
|
||
value={formData.poolspa}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="Yes- Pool Only">Yes- Pool Only</option>
|
||
<option value="Yes- SPA only">Yes- SPA only</option>
|
||
<option value="Yes - Both Pool and SPA">
|
||
Yes - Both Pool and SPA
|
||
</option>
|
||
<option value="4">None</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
Fire places
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="fireplaces"
|
||
value={formData.fireplaces}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="yes">Yes</option>
|
||
<option value="no">No</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
A/C
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="ac"
|
||
value={formData.ac}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="Central">Central</option>
|
||
<option value="Heat Pump">Heat Pump</option>
|
||
<option value="Warm Air">Warm Air</option>
|
||
<option value="Forced Air">Forced Air</option>
|
||
<option value="Gas">Gas</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
Heating
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="heating"
|
||
value={formData.heating}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="Central">Central</option>
|
||
<option value="Heat Pump">Heat Pump</option>
|
||
<option value="Warm Air">Warm Air</option>
|
||
<option value="Forced Air">Forced Air</option>
|
||
<option value="Gas">Gas</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
Building Style
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="buildingstyle"
|
||
value={formData.buildingstyle}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="One Story">One Story</option>
|
||
<option value="Craftsman">Craftsman</option>
|
||
<option value="Log/Cabin">Log/Cabin</option>
|
||
<option value="Split-Level">Split-Level</option>
|
||
<option value="Split-Foyer">Split-Foyer</option>
|
||
<option value="Stick Built">Stick Built</option>
|
||
<option value="Single wide">Single wide</option>
|
||
<option value="Double wide">Double wide</option>
|
||
<option value="Duplex">Duplex</option>
|
||
<option value="Triplex">Triplex</option>
|
||
<option value="Quadruplex">Quadruplex</option>
|
||
<option value="Two Story">Two Story</option>
|
||
<option value="Victorian">Victorian</option>
|
||
<option value="Tudor">Tudor</option>
|
||
<option value="Modern">Modern</option>
|
||
<option value="Art Deco">Art Deco</option>
|
||
<option value="Bungalow">Bungalow</option>
|
||
<option value="Mansion">Mansion</option>
|
||
<option value="Farmhouse">Farmhouse</option>
|
||
<option value="Conventional">Conventional</option>
|
||
<option value="Ranch">Ranch</option>
|
||
<option value="Ranch with Basement">
|
||
Ranch with Basement
|
||
</option>
|
||
<option value="Cape Cod">Cape Cod</option>
|
||
<option value="Contemporary">Contemporary</option>
|
||
<option value="Colonial">Colonial</option>
|
||
<option value="Mediterranean">Mediterranean</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
Site Vacant
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="sitevacant"
|
||
value={formData.sitevacant}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please select</option>
|
||
<option value="Yes">Yes</option>
|
||
<option value="No">No</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
Ext Wall
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="extwall"
|
||
value={formData.extwall}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="Brick">Brick</option>
|
||
<option value="Brick/Vinyl Siding">
|
||
Brick/Vinyl Siding
|
||
</option>
|
||
<option value="Wood/Vinyl Siding">
|
||
Wood/Vinyl Siding
|
||
</option>
|
||
<option value="Brick/Wood Siding">
|
||
Brick/Wood Siding
|
||
</option>
|
||
<option value="Stone">Stone</option>
|
||
<option value="Masonry">Masonry</option>
|
||
<option value="Metal">Metal</option>
|
||
<option value="Fiberboard">Fiberboard</option>
|
||
<option value="Asphalt Siding">Asphalt Siding</option>
|
||
<option value="Concrete Block">Concrete Block</option>
|
||
<option value="Gable">Gable</option>
|
||
<option value="Brick Veneer">Brick Veneer</option>
|
||
<option value="Frame">Frame</option>
|
||
<option value="Siding">Siding</option>
|
||
<option value="Cement/Wood Fiber Siding">
|
||
Cement/Wood Fiber Siding
|
||
</option>
|
||
<option value="Fiber/Cement Siding">
|
||
Fiber/Cement Siding
|
||
</option>
|
||
<option value="Wood Siding">Wood Siding</option>
|
||
<option value="Vinyl Siding">Vinyl Siding</option>
|
||
<option value="Aluminium Siding">
|
||
Aluminium Siding
|
||
</option>
|
||
<option value="Wood/Vinyl Siding">
|
||
Alum/Vinyl Siding
|
||
</option>
|
||
</select>
|
||
</div>
|
||
<div className="col-md-4">
|
||
Roofing
|
||
<select
|
||
className="form-floating mb-3 form-control"
|
||
name="roofing"
|
||
value={formData.roofing}
|
||
onChange={handleChange}
|
||
required
|
||
>
|
||
<option value="">Please Select</option>
|
||
<option value="N/A">N/A</option>
|
||
<option value="Asphalt Shingle">Asphalt Shingle</option>
|
||
<option value="Green Roofs">Green Roofs</option>
|
||
<option value="Built-up Roofing">
|
||
Built-up Roofing
|
||
</option>
|
||
<option value="Composition Shingle">
|
||
Composition Shingle
|
||
</option>
|
||
<option value="Composition Shingle Heavy">
|
||
Composition Shingle Heavy
|
||
</option>
|
||
<option value="Solar tiles">Solar tiles</option>
|
||
<option value="Metal">Metal</option>
|
||
<option value="Stone-coated steel">
|
||
Stone-coated steel
|
||
</option>
|
||
<option value="Slate">Slate</option>
|
||
<option value="Rubber Slate">Rubber Slate</option>
|
||
<option value="Clay and Concrete tiles">
|
||
Clay and Concrete tiles
|
||
</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<div className="form-floating mb-3">
|
||
Total SQFT
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalSqft"
|
||
value={formData.totalSqft}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<h3
|
||
style={{
|
||
color: "#fda417",
|
||
border: "#fda417",
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
<br />
|
||
Property Tax Information
|
||
</h3>
|
||
<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
|
||
}}
|
||
/>
|
||
|
||
{formData.propertyTaxInfo &&
|
||
formData.propertyTaxInfo.map((taxInfo, index) => (
|
||
<div className="row gy-4" key={index}>
|
||
<div className="col-md-3">
|
||
<div className="form-floating mb-3">
|
||
Property Tax Owned
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="propertytaxowned"
|
||
value={taxInfo.propertytaxowned}
|
||
onChange={(e) =>
|
||
handleInputChange(e, index, "propertyTaxInfo")
|
||
}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-2">
|
||
<div className="form-floating mb-2">
|
||
Owned Year
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="ownedyear"
|
||
value={taxInfo.ownedyear}
|
||
onChange={(e) =>
|
||
handleInputChange(e, index, "propertyTaxInfo")
|
||
}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-2">
|
||
<div className="form-floating mb-2">
|
||
Tax Assessed
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="taxassessed"
|
||
value={taxInfo.taxassessed}
|
||
onChange={(e) =>
|
||
handleInputChange(e, index, "propertyTaxInfo")
|
||
}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-2">
|
||
<div className="form-floating mb-2">
|
||
Tax Year
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="taxyear"
|
||
value={taxInfo.taxyear}
|
||
onChange={(e) =>
|
||
handleInputChange(e, index, "propertyTaxInfo")
|
||
}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="col-md-3">
|
||
<div className="form-floating mb-2">
|
||
<br />
|
||
<button
|
||
className="btn btn-danger"
|
||
onClick={() => deletePropertyTaxField(index)}
|
||
style={{ height: "25px", width: "35px" }}
|
||
>
|
||
X
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<button
|
||
className="btn btn-secondary"
|
||
onClick={addPropertyTaxField}
|
||
>
|
||
+ Add Another Property Tax Info
|
||
</button>
|
||
</form>
|
||
|
||
<button
|
||
className="btn btn-primary continue"
|
||
onClick={handleContinue}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
Continue
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === "Images" && (
|
||
<div role="tabpanel" className="card tab-pane active">
|
||
<h3
|
||
style={{
|
||
color: "#fda417",
|
||
border: "#fda417",
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
Upload Images{" "}
|
||
</h3>
|
||
<form>
|
||
<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
|
||
}}
|
||
/>
|
||
|
||
{formData.images.map((image, index) => (
|
||
<div key={index} className="row gy-3 align-items-center">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
value={image.title}
|
||
placeholder="Image Title"
|
||
onChange={(e) => handleImageTitleChange(index, e)}
|
||
/>
|
||
</div>
|
||
<div className="col-md-4 d-flex align-items-center">
|
||
<FileBase64
|
||
multiple={false}
|
||
onDone={(file) => handleImageChange(file, index)}
|
||
/>
|
||
<button
|
||
type="button"
|
||
className="btn btn-danger"
|
||
onClick={() => handleDeleteImage(index)}
|
||
style={{
|
||
marginLeft: "5px", // Adjust this to minimize space between the buttons
|
||
}}
|
||
>
|
||
Delete
|
||
</button>
|
||
</div>
|
||
|
||
{image.file && (
|
||
<div className="col-md-12">
|
||
<img
|
||
src={image.file}
|
||
alt="uploaded"
|
||
style={{ width: "150px", height: "150px" }}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
))}
|
||
|
||
<button
|
||
type="button"
|
||
className="btn btn-primary"
|
||
onClick={handleAddImage}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
+ Add Image
|
||
</button>
|
||
|
||
<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="mb-3">
|
||
<label htmlFor="googleMapLink" className="form-label">
|
||
<h3
|
||
style={{
|
||
color: "#fda417",
|
||
border: "#fda417",
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
Google Maps Link{" "}
|
||
</h3>
|
||
</label>
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="googleMapLink"
|
||
value={formData.googleMapLink}
|
||
onChange={handleChange}
|
||
placeholder="Enter Google Maps link"
|
||
/>
|
||
</div>
|
||
|
||
{formData.googleMapLink && (
|
||
<iframe
|
||
title="Google Map"
|
||
width="100%"
|
||
height="300"
|
||
src={`https://www.google.com/maps/embed/v1/view?key=YOUR_API_KEY¢er=${formData.googleMapLink}&zoom=10`}
|
||
frameBorder="0"
|
||
allowFullScreen
|
||
></iframe>
|
||
)}
|
||
</form>
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={handleBack}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
Go Back
|
||
</button>{" "}
|
||
<button
|
||
className="btn btn-primary continue"
|
||
onClick={handleContinue}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
Continue
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === "Accounting" && (
|
||
<div
|
||
className="card"
|
||
style={{
|
||
color: "#fda417",
|
||
border: "1px solid #fda417",
|
||
padding: "10px",
|
||
borderRadius: "8px",
|
||
}}
|
||
>
|
||
<br />
|
||
|
||
<div className="row gy-3 col-16">
|
||
{/* Close Date A to B */}
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Close Date A to B"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="date"
|
||
className="form-control"
|
||
name="closeDateAtoB"
|
||
value={formData.closeDateAtoB}
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
setFormData({
|
||
...formData,
|
||
closeDateAtoB: value,
|
||
});
|
||
calculateTurnTime(value, formData.closeDateBtoC);
|
||
}}
|
||
placeholder="Close Date A to B"
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
</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 className="row gy-3">
|
||
{/* Close Date B to C */}
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Close Date B to C"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="date"
|
||
className="form-control"
|
||
name="closeDateBtoC"
|
||
value={formData.closeDateBtoC}
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
setFormData({
|
||
...formData,
|
||
closeDateBtoC: value,
|
||
});
|
||
calculateTurnTime(formData.closeDateAtoB, value);
|
||
}}
|
||
placeholder="Close Date B to C"
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
</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.closeDateBtoC).toLocaleDateString(
|
||
"en-US",
|
||
{
|
||
month: "numeric",
|
||
day: "numeric",
|
||
year: "numeric",
|
||
}
|
||
)}
|
||
</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Renovation Risk
|
||
</span>
|
||
|
||
<div className="col-md-7">
|
||
{renovationRiskOptions.map((option) => (
|
||
<div
|
||
className="form-check form-check-inline"
|
||
key={option}
|
||
>
|
||
<input
|
||
className="form-check-input"
|
||
type="radio"
|
||
name="renovationRisk"
|
||
id={`renovationRisk${option}`}
|
||
value={option}
|
||
checked={formData.renovationRisk === option}
|
||
onChange={(e) => {
|
||
const value = parseInt(e.target.value, 10);
|
||
setFormData({
|
||
...formData,
|
||
renovationRisk: value,
|
||
});
|
||
}}
|
||
/>
|
||
<label
|
||
className="form-check-label"
|
||
htmlFor={`renovationRisk${option}`}
|
||
>
|
||
{option}
|
||
</label>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Rate of Return
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="rateofreturn"
|
||
value={`$ ${calculaterateofreturn().toFixed(2)}`}
|
||
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 />
|
||
|
||
<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 />
|
||
|
||
<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 that’s 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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Costs paid out of Closing Hud A to B:
|
||
</span>
|
||
|
||
{formData.costPaidAtoB.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) =>
|
||
handleCostChange(index, "title", e.target.value)
|
||
}
|
||
placeholder="Title"
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
cost.isInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={`$ ${cost.price}`}
|
||
onChange={(e) => handlePriceChange(e, index)}
|
||
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={() => deleteCost(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
onClick={addCost}
|
||
className="btn btn-primary back"
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Extra Cost
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Purchase Cost
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalPurchaseCosts"
|
||
value={`$ ${calculateTotalPurchaseCosts().toFixed(2)}`} // Add dollar sign before the calculated total and format it to 2 decimal places
|
||
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>
|
||
<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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Credits received on settlement:
|
||
</span>
|
||
|
||
{formData.credits.map((credits, index) => (
|
||
<div key={index} className="row gy-3 align-items-center">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
value={credits.title}
|
||
onChange={(e) =>
|
||
handleCreditChange(index, "title", e.target.value)
|
||
}
|
||
placeholder="credits"
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
credits.isInvalid ? "is-invalid" : ""
|
||
}`} // Apply 'is-invalid' class when invalid
|
||
value={credits.price}
|
||
onChange={(e) => handleCreditPriceChange(e, index)} // New handler for price validation
|
||
placeholder="Price"
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{credits.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={() => deleteCredits(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addCredits}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add credits
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total credits received on settlement
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalcredits"
|
||
value={calculateTotalCredits()}
|
||
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>
|
||
<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",
|
||
}}
|
||
>
|
||
Total Purchase Cost after Credits Received
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalPurchaseCostsaftercredits"
|
||
value={calculateTotalPurchaseCostsWithCredits()}
|
||
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>
|
||
<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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Cash Adjustments:
|
||
</span>
|
||
|
||
{formData.cashAdjustments.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) =>
|
||
handlecashAdjustmentsTitle(
|
||
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) =>
|
||
handlecashAdjustmentsCostChange(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={() => deletecashAdjustments(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addcashAdjustments}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Cash Adjustments
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Cash Adjustments on Settlement
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalcashAdjustments"
|
||
value={calculatecashAdjustments()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Total Cash Required on Settlement
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalcashrequiredonsettlement"
|
||
value={calculateTotalCashRequiredonSettlement()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Incidental Cost:
|
||
</span>
|
||
|
||
{formData.incidentalCost.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) =>
|
||
handleincidentalCostTitle(
|
||
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) => handleincidentalCostChange(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={() => deleteincidentalCost(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addincidentalCost}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Incidental Cost
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Incidental Cost
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalincidentalCost"
|
||
value={calculateTotalincidentalCost()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Carry Costs:
|
||
</span>
|
||
|
||
{formData.carryCosts.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) =>
|
||
handlecarryCostsTitle(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) => handlecarryCostsChange(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={() => deletecarryCosts(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addcarryCosts}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Carry Cost
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Carry Cost
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalcarryCosts"
|
||
value={calculatetotalcarryCosts()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Reno/Construction
|
||
</span>
|
||
|
||
{formData.renovationCost.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) =>
|
||
handlerenovationCostTitle(
|
||
index,
|
||
"title",
|
||
e.target.value
|
||
)
|
||
}
|
||
placeholder="Title"
|
||
required
|
||
style={{
|
||
fontSize: "10px", // Set the desired font size
|
||
}}
|
||
/>
|
||
</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) => handlerenovationCostChange(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={() => deleterenovationCost(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addrenovationCost}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Reno/Construction
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Renovation Cost
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalrenovationCost"
|
||
value={calculaterenovationCost()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Total Renovations & Holding Cost
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalRenovationsandHoldingCost"
|
||
value={calculatetotalRenovationsandHoldingCost()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Total Costs to Buy A to B
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalCoststoBuyAtoB"
|
||
value={calculatetotalCoststoBuyAtoB()}
|
||
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
|
||
/>
|
||
{formData.isInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
<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",
|
||
}}
|
||
>
|
||
Selling Price B to C
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||
}`}
|
||
name="sellingPriceBtoC"
|
||
value={formData.sellingPriceBtoC}
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
sellingPriceBtoC: 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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Less:Costs paid out of closing Hud B to C:
|
||
</span>
|
||
|
||
{formData.costPaidOutofClosing.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) =>
|
||
handlecostPaidOutofClosingTitle(
|
||
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) =>
|
||
handlecostPaidOutofClosingChange(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={() => deletecostPaidOutofClosing(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addcostPaidOutofClosing}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Cost Paid Out of Closing
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total cost paid out of closing
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalcostPaidOutofClosing"
|
||
value={calculateTotalcostPaidOutofClosing()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Total Cost to Sell B to C
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalCosttoSellBtoC"
|
||
value={calculateTotalCosttoSellBtoC()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Gross Proceeds per HUD
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="grossproceedsperHUD"
|
||
value={calculateTotalCosttoSellBtoC()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Adjustments:
|
||
</span>
|
||
|
||
{formData.adjustments.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) =>
|
||
handleadjustmentsTitle(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) => handleadjustmentsChange(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={() => deleteadjustments(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addadjustments}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Adjustments
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Adjustments
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totaladjustments"
|
||
value={calculateTotaladjustments()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Funds Available for distribution
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="fundsavailablefordistribution"
|
||
value={calculatefundsavailablefordistribution()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Income Statement Adjustments:
|
||
</span>
|
||
|
||
{formData.incomestatement.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) =>
|
||
handleincomestatementTitle(
|
||
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) => handleincomestatementChange(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={() => deleteincomestatement(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addincomestatement}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Income Statement
|
||
</button>
|
||
</div>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Total Income Statement Adjustment
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalincomestatement"
|
||
value={calculateTotalincomestatement()}
|
||
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
|
||
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",
|
||
}}
|
||
>
|
||
Net B to C Sale Value
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="netBtoCsalevalue"
|
||
value={calculatenetBtoCsalevalue()}
|
||
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
|
||
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
|
||
}}
|
||
/>
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Net Profit Computation
|
||
</span>
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Total Costs to Buy A to B"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="totalCoststoBuyAtoBagain"
|
||
value={calculatetotalCoststoBuyAtoB()}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Funds Prior to Closing"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isfundspriortoclosingInvalid
|
||
? "is-invalid"
|
||
: ""
|
||
}`}
|
||
value={formData.fundspriortoclosing}
|
||
name="fundspriortoclosing"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
fundspriortoclosing: value,
|
||
isfundspriortoclosingInvalid: !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,
|
||
isfundspriortoclosingInvalid: true, // Set isPurchaseCostInvalid to true to show the alert
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isfundspriortoclosingInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Net B to C Sale Value"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="netBtoCsalevalue"
|
||
value={calculatenetBtoCsalevalue()}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Short Term Rental"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={formData.shorttermrental}
|
||
name="shorttermrental"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
shorttermrental: 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
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isPurchaseCostInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Other Income"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={formData.OtherIncome}
|
||
name="OtherIncome"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
OtherIncome: 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
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isPurchaseCostInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Insurance Claim"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={formData.InsuranceClaim}
|
||
name="InsuranceClaim"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
InsuranceClaim: 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
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isPurchaseCostInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
placeholder="Long Term Rental"
|
||
required
|
||
disabled
|
||
/>
|
||
</div>
|
||
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isPurchaseCostInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={formData.LongTermRental}
|
||
name="LongTermRental"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
LongTermRental: 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
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isPurchaseCostInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<br />
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Net Profit Before Financing Costs
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="netprofitbeforefinancingcosts"
|
||
value={calculateNetProfitBeforeFinancingCosts()}
|
||
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>
|
||
|
||
<br />
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Financing Cost/Other Closing Costs
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
formData.isFinancingCostClosingCostInvalid
|
||
? "is-invalid"
|
||
: ""
|
||
}`}
|
||
value={formData.FinancingCostClosingCost}
|
||
name="FinancingCostClosingCost"
|
||
onChange={(e) => {
|
||
const value = e.target.value;
|
||
const isValid = /^\d*\.?\d*$/.test(value); // Regex to allow only numbers and decimal points
|
||
setFormData({
|
||
...formData,
|
||
FinancingCostClosingCost: value,
|
||
isFinancingCostClosingCostInvalid: !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,
|
||
isFinancingCostClosingCostInvalid: true, // Set isPurchaseCostInvalid to true to show the alert
|
||
});
|
||
}
|
||
}}
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{formData.isFinancingCostClosingCostInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid number.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div className="row gy-3 align-items-center">
|
||
<span
|
||
className="col-md-4"
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Net Profit
|
||
</span>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
name="netprofit"
|
||
value={calculateNetProfit()}
|
||
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>
|
||
|
||
<br />
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={handleBack}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
Go Back
|
||
</button>{" "}
|
||
<button
|
||
type="button"
|
||
className="btn btn-primary continue"
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
onClick={handleSubmit}
|
||
>
|
||
Submit
|
||
</button>{" "}
|
||
</div>
|
||
<br />
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default EditProperty;
|