4445 lines
164 KiB
JavaScript
4445 lines
164 KiB
JavaScript
import { useDispatch, useSelector } from "react-redux";
|
||
import { submitProperty } from "../redux/features/propertySlice";
|
||
import { useState, useEffect } from "react";
|
||
import Navbar from "./Navbar";
|
||
import { toast } from "react-toastify";
|
||
import "react-toastify/dist/ReactToastify.css";
|
||
import FileBase64 from "react-file-base64";
|
||
import "../addproperty.css";
|
||
|
||
const Addproperty = () => {
|
||
const [activeTab, setActiveTab] = useState("propertydetails");
|
||
const handleContinue = () => {
|
||
if (activeTab === "propertydetails") setActiveTab("Images");
|
||
if (activeTab === "Images") setActiveTab("Accounting");
|
||
if (activeTab === "Accounting") setActiveTab("IAB");
|
||
if (activeTab === "IAB") setActiveTab("IAB");
|
||
};
|
||
|
||
const handleBack = () => {
|
||
if (activeTab === "Images") setActiveTab("propertydetails");
|
||
if (activeTab === "Accounting") setActiveTab("Images");
|
||
if (activeTab === "IAB") setActiveTab("Accounting");
|
||
};
|
||
|
||
const dispatch = useDispatch();
|
||
const { status, error } = useSelector((state) => state.property);
|
||
const { user } = useSelector((state) => ({ ...state.auth }));
|
||
const renovationRiskOptions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // Array of options
|
||
|
||
const [formData, setFormData] = useState({
|
||
propertyTaxInfo: [
|
||
{ propertytaxowned: "0", ownedyear: "0", taxassessed: "0", taxyear: "0" },
|
||
],
|
||
images: [{ title: "", file: "" }],
|
||
googleMapLink: "", // Field for Google Maps link
|
||
renovationRisk: null,
|
||
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" },
|
||
],
|
||
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",
|
||
TradesinRenovations: [
|
||
{ title: "Planning & Design", price: "0" },
|
||
{ title: "Demolition & Cleanup", price: "0" },
|
||
{ title: "Framing", price: "0" },
|
||
{ title: "Rough-in Services", price: "0" },
|
||
{ title: "Structural Repairs", price: "0" },
|
||
{ title: "Insulation & Drywall", price: "0" },
|
||
{ title: "Cabinetry & Countertops", price: "0" },
|
||
{ title: "Fixtures & Appliances", price: "0" },
|
||
{ title: "Flooring and Tiling", price: "0" },
|
||
{ title: "Plumbing", price: "0" },
|
||
{ title: "Electrical", price: "0" },
|
||
{ title: "HVAC", price: "0" },
|
||
{ title: "Painting", price: "0" },
|
||
{ title: "Interior Finishes", price: "0" },
|
||
{ title: "Exterior Work", price: "0" },
|
||
{ title: "Final Inspections", price: "0" },
|
||
{ title: "Punch List", price: "0" },
|
||
{ title: "Staging", price: "0" },
|
||
],
|
||
IAB: [{ title: "IAB Title", URL: "Please enter URL" }],
|
||
files: [{ title: "", file: "" }],
|
||
});
|
||
|
||
const [submitted, setSubmitted] = useState(false);
|
||
|
||
const handleImageChange = (file, index) => {
|
||
console.log("File received:", file); // Debugging log to check the file object
|
||
const updatedImages = [...formData.images];
|
||
updatedImages[index].file = file.base64; // store base64 format of 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].title = e.target.value;
|
||
setFormData({ ...formData, images: updatedImages });
|
||
};
|
||
|
||
const handleInputChange = (e, index, fieldName) => {
|
||
const { name, value } = e.target;
|
||
if (fieldName === "propertyTaxInfo") {
|
||
const updatedPropertyTaxInfo = [...formData.propertyTaxInfo];
|
||
updatedPropertyTaxInfo[index][name] = value;
|
||
setFormData({ ...formData, propertyTaxInfo: updatedPropertyTaxInfo });
|
||
} else {
|
||
setFormData({ ...formData, [name]: value });
|
||
}
|
||
};
|
||
|
||
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 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;
|
||
};
|
||
|
||
const handleSubmit = () => {
|
||
if (
|
||
formData.address &&
|
||
formData.city &&
|
||
formData.state &&
|
||
formData.county &&
|
||
formData.zip &&
|
||
formData.parcel &&
|
||
formData.subdivision &&
|
||
formData.legal &&
|
||
formData.costpersqft &&
|
||
formData.propertyType &&
|
||
formData.lotacres &&
|
||
formData.yearBuild &&
|
||
formData.totallivingsqft &&
|
||
formData.beds &&
|
||
formData.baths &&
|
||
formData.stories &&
|
||
formData.garage &&
|
||
formData.garagesqft &&
|
||
formData.poolspa &&
|
||
formData.fireplaces &&
|
||
formData.ac &&
|
||
formData.heating &&
|
||
formData.buildingstyle &&
|
||
formData.sitevacant &&
|
||
formData.extwall &&
|
||
formData.roofing &&
|
||
formData.totalSqft &&
|
||
formData.renovationRisk &&
|
||
formData.closeDateAtoB &&
|
||
formData.closeDateBtoC &&
|
||
formData.purchaseCost &&
|
||
formData.sellingPriceBtoC &&
|
||
formData.fundspriortoclosing &&
|
||
formData.shorttermrental &&
|
||
formData.OtherIncome &&
|
||
formData.InsuranceClaim &&
|
||
formData.LongTermRental &&
|
||
formData.FinancingCostClosingCost &&
|
||
formData.TradesinRenovations
|
||
) {
|
||
const rateofreturn = calculaterateofreturn();
|
||
const totalPurchaseCosts = calculateTotalPurchaseCosts();
|
||
const totalPurchaseCostsaftercredits =
|
||
calculateTotalPurchaseCostsWithCredits();
|
||
const totalcashAdjustments = calculatecashAdjustments();
|
||
const totalincidentalCost = calculateTotalincidentalCost();
|
||
const totalcredits = calculateTotalCredits();
|
||
const totalcashrequiredonsettlement =
|
||
calculateTotalCashRequiredonSettlement();
|
||
const totalcarryCosts = calculatetotalcarryCosts();
|
||
const totalrenovationCost = calculaterenovationCost();
|
||
const totalRenovationsandHoldingCost =
|
||
calculatetotalRenovationsandHoldingCost();
|
||
const totalCoststoBuyAtoB = calculatetotalCoststoBuyAtoB();
|
||
const totalcostPaidOutofClosing = calculateTotalcostPaidOutofClosing();
|
||
const totaladjustments = calculateTotaladjustments();
|
||
const fundsavailablefordistribution =
|
||
calculatefundsavailablefordistribution();
|
||
const grossproceedsperHUD = calculateTotalCosttoSellBtoC();
|
||
const totalCosttoSellBtoC = calculateTotalCosttoSellBtoC();
|
||
const totalincomestatement = calculateTotalincomestatement();
|
||
const netBtoCsalevalue = calculatenetBtoCsalevalue();
|
||
const netprofitbeforefinancingcosts =
|
||
calculateNetProfitBeforeFinancingCosts();
|
||
const NetProfit = calculateNetProfit();
|
||
|
||
// Add user info to formData, including the propertyTaxInfo array
|
||
const formDataWithUserInfo = {
|
||
...formData,
|
||
userfirstname: user?.result?.firstName,
|
||
usermiddlename: user?.result?.middleName,
|
||
userlastname: user?.result?.lastName,
|
||
usertitle: user?.result?.title,
|
||
useremail: user?.result?.email,
|
||
userId: user?.result?.userId,
|
||
totalPurchaseCosts: totalPurchaseCosts,
|
||
totalcredits: totalcredits,
|
||
totalPurchaseCostsaftercredits: totalPurchaseCostsaftercredits,
|
||
totalcashAdjustments: totalcashAdjustments,
|
||
totalcashrequiredonsettlement: totalcashrequiredonsettlement,
|
||
totalincidentalCost: totalincidentalCost,
|
||
totalcarryCosts: totalcarryCosts,
|
||
totalrenovationCost: totalrenovationCost,
|
||
totalRenovationsandHoldingCost: totalRenovationsandHoldingCost,
|
||
totalCoststoBuyAtoB: totalCoststoBuyAtoB,
|
||
totalcostPaidOutofClosing: totalcostPaidOutofClosing,
|
||
totaladjustments: totaladjustments,
|
||
fundsavailablefordistribution: fundsavailablefordistribution,
|
||
grossproceedsperHUD: grossproceedsperHUD,
|
||
totalCosttoSellBtoC: totalCosttoSellBtoC,
|
||
totalincomestatement: totalincomestatement,
|
||
netBtoCsalevalue: netBtoCsalevalue,
|
||
netprofitbeforefinancingcosts: netprofitbeforefinancingcosts,
|
||
NetProfit: NetProfit,
|
||
rateofreturn: rateofreturn,
|
||
};
|
||
|
||
// Check if propertyTaxInfo is an array and has values
|
||
if (
|
||
Array.isArray(formData.propertyTaxInfo) &&
|
||
formData.propertyTaxInfo.length > 0
|
||
) {
|
||
formDataWithUserInfo.propertyTaxInfo = formData.propertyTaxInfo; // Include propertyTaxInfo
|
||
} else {
|
||
formDataWithUserInfo.propertyTaxInfo = []; // Ensure it's an empty array if not filled
|
||
}
|
||
|
||
// Dispatch the form data with user info
|
||
dispatch(submitProperty(formDataWithUserInfo));
|
||
setSubmitted(true);
|
||
} else {
|
||
toast.error("Please fill all fields before submitting", {
|
||
position: "top-right",
|
||
autoClose: 3000,
|
||
});
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
if (submitted) {
|
||
if (status === "succeeded") {
|
||
toast.success("Property submitted successfully!", {
|
||
position: "top-right",
|
||
autoClose: 3000,
|
||
});
|
||
setSubmitted(false);
|
||
} else if (status === "failed") {
|
||
toast.error(`Failed to submit: ${error}`, {
|
||
position: "top-right",
|
||
autoClose: 3000,
|
||
});
|
||
setSubmitted(false);
|
||
}
|
||
}
|
||
}, [status, error, submitted]);
|
||
|
||
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 addTrade = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
TradesinRenovations: [...prevData.TradesinRenovations, { title: "", price: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteTrade = (index) => {
|
||
const updatedCosts = formData.TradesinRenovations.filter((_, i) => i !== index);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
TradesinRenovations: updatedCosts,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to title and price
|
||
const handleTrade = (index, field, value) => {
|
||
const updatedCosts = [...formData.TradesinRenovations];
|
||
updatedCosts[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
TradesinRenovations: updatedCosts,
|
||
}));
|
||
};
|
||
|
||
const handleTradePrice = (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.TradesinRenovations.map((cost, i) =>
|
||
i === index
|
||
? { ...cost, price: value, isInvalid: false } // Reset isInvalid if valid number
|
||
: cost
|
||
);
|
||
setFormData({ ...formData, TradesinRenovations: updatedCosts });
|
||
} else {
|
||
const updatedCosts = formData.TradesinRenovations.map((cost, i) =>
|
||
i === index
|
||
? { ...cost, isInvalid: true } // Keep isInvalid true for invalid input
|
||
: cost
|
||
);
|
||
setFormData({ ...formData, TradesinRenovations: updatedCosts });
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
const addIAB = () => {
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
IAB: [...prevData.IAB, { title: "", URL: "" }],
|
||
}));
|
||
};
|
||
|
||
const deleteIAB = (index) => {
|
||
const updatedIAB = formData.IAB.filter(
|
||
(_, i) => i !== index
|
||
);
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
IAB: updatedIAB,
|
||
}));
|
||
};
|
||
|
||
// Function to handle changes to incidentalCost title and price
|
||
const handleIABTitle = (index, field, value) => {
|
||
const updatedIAB = [...formData.IAB];
|
||
updatedIAB[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
IAB: updatedIAB,
|
||
}));
|
||
};
|
||
|
||
const handleIABChange = (index, field, value) => {
|
||
const updatedIAB = [...formData.IAB];
|
||
updatedIAB[index][field] = value;
|
||
setFormData((prevData) => ({
|
||
...prevData,
|
||
IAB: updatedIAB,
|
||
}));
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<div className="container tabs-wrap">
|
||
<Navbar />
|
||
|
||
<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>
|
||
<li
|
||
role="presentation"
|
||
className={activeTab === "IAB" ? "active tab" : "tab"}
|
||
>
|
||
<a onClick={() => setActiveTab("IAB")} role="tab">
|
||
IAB Verified Report
|
||
</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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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={handleInputChange}
|
||
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.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>
|
||
{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",
|
||
}}
|
||
>
|
||
Delete
|
||
</button>
|
||
</div>
|
||
|
||
{/* Check if image.file contains valid base64 data */}
|
||
{image.file && (
|
||
<>
|
||
<p>Base64 Data:</p> {/* Debugging base64 data */}
|
||
<pre>{image.file.slice(0, 100)}...</pre> {/* Display first 100 characters for debugging */}
|
||
|
||
<div className="col-md-12">
|
||
<img
|
||
src={image.file}
|
||
alt="uploaded"
|
||
style={{ width: "150px", height: "150px", objectFit: "cover" }}
|
||
/>
|
||
</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={handleInputChange}
|
||
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">
|
||
{/* 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()}
|
||
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 />
|
||
|
||
<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>
|
||
|
||
<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={handleContinue}
|
||
>
|
||
Continue
|
||
</button>{" "}
|
||
</div>
|
||
<br />
|
||
</div>
|
||
)}
|
||
|
||
|
||
|
||
{activeTab === "IAB" && (
|
||
<div role="tabpanel" className="card tab-pane active">
|
||
|
||
|
||
|
||
|
||
<span
|
||
style={{
|
||
color: "#fda417",
|
||
fontSize: "14px",
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
Trades in Renovations
|
||
</span>
|
||
|
||
{formData.TradesinRenovations.map((title, index) => (
|
||
<div key={index} className="row gy-3 align-items-center">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
value={title.title}
|
||
onChange={(e) =>
|
||
handleTrade(index, "title", e.target.value)
|
||
}
|
||
placeholder="Title"
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className={`form-control ${
|
||
title.isInvalid ? "is-invalid" : ""
|
||
}`}
|
||
value={`$ ${title.price}`}
|
||
onChange={(e) => handleTradePrice(e, index)}
|
||
placeholder="Price"
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{title.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={() => deleteTrade(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
onClick={addTrade}
|
||
className="btn btn-primary back"
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add Trades in Renovations
|
||
</button>
|
||
</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",
|
||
}}
|
||
>
|
||
Add IAB Links:
|
||
</span>
|
||
|
||
{formData.IAB.map((title, index) => (
|
||
<div key={index} className="row gy-3 align-items-center">
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
value={title.title}
|
||
onChange={(e) =>
|
||
handleIABTitle(index, "title", e.target.value)
|
||
}
|
||
placeholder="Title"
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="col-md-4">
|
||
<input
|
||
type="text"
|
||
className="form-control"
|
||
value={title.URL}
|
||
onChange={(e) =>
|
||
handleIABChange(index, "URL", e.target.value)
|
||
}
|
||
placeholder="URL"
|
||
style={{ textAlign: "right" }}
|
||
required
|
||
/>
|
||
{title.isInvalid && (
|
||
<div className="invalid-feedback">
|
||
Please enter a valid URL.
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
|
||
<div className="col-md-2 d-flex justify-content-start">
|
||
<button
|
||
className="btn btn-danger"
|
||
onClick={() => deleteIAB(index)}
|
||
style={{ marginLeft: "5px" }}
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="col-md-4">
|
||
<button
|
||
className="btn btn-primary back"
|
||
onClick={addIAB}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
+
|
||
</span>{" "}
|
||
Add IAB URL
|
||
</button>
|
||
</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
|
||
}}
|
||
/>
|
||
|
||
|
||
<h3
|
||
style={{
|
||
color: "#fda417",
|
||
border: "#fda417",
|
||
fontSize: "20px",
|
||
fontWeight: "normal",
|
||
}}
|
||
>
|
||
Upload Files{" "}
|
||
</h3>
|
||
|
||
{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",
|
||
}}
|
||
>
|
||
Delete
|
||
</button>
|
||
</div>
|
||
|
||
{/* Check if image.file contains valid base64 data */}
|
||
{image.file && (
|
||
<>
|
||
|
||
<div className="col-md-12">
|
||
<img
|
||
src={image.file}
|
||
alt="uploaded"
|
||
style={{ width: "150px", height: "150px", objectFit: "cover" }}
|
||
/>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
))}
|
||
|
||
<button
|
||
type="button"
|
||
className="btn btn-primary"
|
||
onClick={handleAddImage}
|
||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
||
>
|
||
+ Add Image
|
||
</button>
|
||
|
||
<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>
|
||
|
||
|
||
|
||
|
||
|
||
</div>
|
||
)}
|
||
|
||
|
||
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default Addproperty;
|