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 ( <>





{activeTab === "propertydetails" && (

Property Location


Property Address
City
State
County
Zip
Parcel
Sub division
Legal Description