done
This commit is contained in:
parent
2dd33296d0
commit
d02de3dafa
|
@ -34,4 +34,14 @@ export const getFundDetailsById = async (req, res) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ message: error.message });
|
res.status(500).json({ message: error.message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getAllFunds = async (req, res) => {
|
||||||
|
try {
|
||||||
|
// const allFunds = await FundDetailsModal.find();
|
||||||
|
const allFunds = await FundDetailsModal.findOne();
|
||||||
|
res.status(200).json(allFunds);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: "Server error" });
|
||||||
|
}
|
||||||
|
};
|
|
@ -80,9 +80,10 @@ export const getPropertyById = async (req, res) => {
|
||||||
export const updatePropertyById = async (req, res) => {
|
export const updatePropertyById = async (req, res) => {
|
||||||
const { id } = req.params; // This should be the propertyId
|
const { id } = req.params; // This should be the propertyId
|
||||||
const updateData = req.body;
|
const updateData = req.body;
|
||||||
|
const fundDetails=req.body
|
||||||
|
|
||||||
console.log("Received propertyId:", id); // Log the received propertyId
|
console.log("Received propertyId:", id); // Log the received propertyId
|
||||||
console.log("updateData", updateData);
|
console.log("fundDetails", fundDetails);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Find the property by propertyId instead of _id
|
// Find the property by propertyId instead of _id
|
||||||
|
|
|
@ -302,6 +302,7 @@ const propertySchema = mongoose.Schema({
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true, // Set to true if this field is mandatory
|
required: true, // Set to true if this field is mandatory
|
||||||
},
|
},
|
||||||
|
fundDetails:[],
|
||||||
});
|
});
|
||||||
|
|
||||||
const PropertyModal = mongoose.model("property", propertySchema);
|
const PropertyModal = mongoose.model("property", propertySchema);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
import { submitFundDetails, getFundDetailsById } from '../controllers/fundDetails.js';
|
import { submitFundDetails, getFundDetailsById } from '../controllers/fundDetails.js';
|
||||||
|
import { getAllFunds } from '../controllers/fundDetails.js';
|
||||||
|
|
||||||
|
|
||||||
router.post('/', submitFundDetails);
|
router.post('/', submitFundDetails);
|
||||||
|
router.get("/allFunds", getAllFunds);
|
||||||
router.get("/:id", getFundDetailsById);
|
router.get("/:id", getFundDetailsById);
|
||||||
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-YX7OIV1T.js"></script>
|
<script type="module" crossorigin src="/assets/index-CrKcgQxs.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-iEl-il0E.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import EditProperty from "./components/EditProperty";
|
||||||
import SearchProperties from "./components/SearchProperties";
|
import SearchProperties from "./components/SearchProperties";
|
||||||
import ProfileView from "./components/ProfileView";
|
import ProfileView from "./components/ProfileView";
|
||||||
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
@ -31,6 +32,7 @@ const App = () => {
|
||||||
<Route path="/contact" element={<Contact />}></Route>
|
<Route path="/contact" element={<Contact />}></Route>
|
||||||
<Route path="/register" element={<Register />}></Route>
|
<Route path="/register" element={<Register />}></Route>
|
||||||
|
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/registrationsuccess"
|
path="/registrationsuccess"
|
||||||
element={
|
element={
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
import { useState, useEffect } from "react";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { fetchPropertyById } from "../redux/features/propertySlice";
|
|
||||||
import { updateProperty } from "../redux/features/propertySlice";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import Navbar from "./Navbar";
|
|
||||||
import Footer from "./Footer";
|
|
||||||
|
|
||||||
const EditProperty = () => {
|
|
||||||
const { id } = useParams();
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const { selectedProperty } = useSelector((state) => state.property);
|
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
|
||||||
propertyType: "",
|
|
||||||
yearBuild: "",
|
|
||||||
totalSqft: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(fetchPropertyById(id));
|
|
||||||
}, [dispatch, id]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedProperty) {
|
|
||||||
setFormData({
|
|
||||||
propertyType: selectedProperty.propertyType,
|
|
||||||
yearBuild: selectedProperty.yearBuild,
|
|
||||||
totalSqft: selectedProperty.totalSqft,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [selectedProperty]);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
dispatch(updateProperty({ id, propertyData: formData }));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Navbar />
|
|
||||||
<br /> <br /> <br /> <br /> <br /> <br />
|
|
||||||
|
|
||||||
|
|
||||||
<div className="edit-property-form">
|
|
||||||
<h2>Edit Property</h2>
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<div>
|
|
||||||
<select
|
|
||||||
className="form-floating mb-3 form-control"
|
|
||||||
name="propertyType"
|
|
||||||
value={formData.propertyType}
|
|
||||||
onChange={handleChange}
|
|
||||||
required
|
|
||||||
>
|
|
||||||
<option value="">Please Select Property Type</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-12">
|
|
||||||
<div className="form-floating mb-3">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
name="yearBuild"
|
|
||||||
value={formData.yearBuild}
|
|
||||||
onChange={handleChange}
|
|
||||||
placeholder="Year build"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<label htmlFor="yearBuild" className="form-label">
|
|
||||||
Year Build
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="form-floating mb-3">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
name="totalSqft"
|
|
||||||
value={formData.totalSqft}
|
|
||||||
onChange={handleChange}
|
|
||||||
placeholder="Total SQFT"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<label htmlFor="totalSqft" className="form-label">
|
|
||||||
Total SQFT
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit">Update Property</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<Footer />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditProperty;
|
|
|
@ -6,7 +6,10 @@ import propertydummy from "../img/propertydummy.jpg";
|
||||||
import Navbar from "./Navbar";
|
import Navbar from "./Navbar";
|
||||||
import Footer from "./Footer";
|
import Footer from "./Footer";
|
||||||
import { Modal, Button, Form } from "react-bootstrap"; // Importing Modal components
|
import { Modal, Button, Form } from "react-bootstrap"; // Importing Modal components
|
||||||
import { submitFundDetails } from "../redux/features/fundDetailsSlice";
|
import {
|
||||||
|
submitFundDetails,
|
||||||
|
getFundDetailsById,
|
||||||
|
} from "../redux/features/fundDetailsSlice";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const PropertyView = () => {
|
const PropertyView = () => {
|
||||||
|
@ -17,22 +20,39 @@ const PropertyView = () => {
|
||||||
(state) => state.property
|
(state) => state.property
|
||||||
);
|
);
|
||||||
const { user } = useSelector((state) => ({ ...state.auth }));
|
const { user } = useSelector((state) => ({ ...state.auth }));
|
||||||
|
const { fundDetails } = useSelector((state) => state.fundDetails);
|
||||||
|
|
||||||
|
console.log("funddetails", fundDetails);
|
||||||
|
const [activeTab, setActiveTab] = useState("propertydetails");
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true); // Loader state
|
const [loading, setLoading] = useState(true); // Loader state
|
||||||
const [showModal, setShowModal] = useState(false); // Modal state
|
const [showModal, setShowModal] = useState(false); // Modal state
|
||||||
const [fundValue, setFundValue] = useState(""); // Fund value state
|
const [fundValue, setFundValue] = useState(""); // Fund value state
|
||||||
const [fundPercentage, setFundPercentage] = useState(""); // Fund percentage state
|
const [fundPercentage, setFundPercentage] = useState(""); // Fund percentage state
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Fetch the property by ID when the component loads
|
|
||||||
if (id) {
|
if (id) {
|
||||||
dispatch(fetchPropertyById(id));
|
dispatch(fetchPropertyById(id));
|
||||||
setLoading(false);
|
dispatch(getFundDetailsById(id));
|
||||||
}
|
}
|
||||||
}, [id, dispatch]);
|
}, [id, dispatch]);
|
||||||
|
|
||||||
if (status === "loading") {
|
useEffect(() => {
|
||||||
return <p>Loading property details...</p>;
|
if (status === "succeeded") {
|
||||||
}
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (fundDetails) {
|
||||||
|
setFundValue(fundDetails.investmentAmount);
|
||||||
|
setFundPercentage(fundDetails.ownershipPercentage);
|
||||||
|
}
|
||||||
|
}, [fundDetails]);
|
||||||
|
|
||||||
|
// if (status === "loading") {
|
||||||
|
// return <p>Loading property details...</p>;
|
||||||
|
// }
|
||||||
|
|
||||||
if (status === "failed") {
|
if (status === "failed") {
|
||||||
return <p>Error loading property: {error}</p>;
|
return <p>Error loading property: {error}</p>;
|
||||||
|
@ -53,6 +73,10 @@ const PropertyView = () => {
|
||||||
// Inside your PropertyView component
|
// Inside your PropertyView component
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (fundValue <= 0 || fundPercentage <= 0 || fundPercentage > 100) {
|
||||||
|
alert("Please enter valid values.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fundDetails = {
|
const fundDetails = {
|
||||||
propertyOwnerId: selectedProperty?.userId,
|
propertyOwnerId: selectedProperty?.userId,
|
||||||
|
@ -70,217 +94,310 @@ const PropertyView = () => {
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<br /> <br /> <br /> <br />
|
<br /> <br /> <br /> <br />
|
||||||
<div className="container col-12">
|
<br /> <br />
|
||||||
{loading ? (
|
<div className="container tabs-wrap col-12">
|
||||||
<div className="loader">Loading...</div> // Loader
|
<Navbar />
|
||||||
) : selectedProperty ? (
|
|
||||||
<div className="py-3 py-md-5 bg-light">
|
|
||||||
<div className="card-header bg-white">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-5 mt-3">
|
|
||||||
<div>
|
|
||||||
{selectedProperty.images && selectedProperty.images[0] ? (
|
|
||||||
<img
|
|
||||||
src={selectedProperty.images[0].file || propertydummy}
|
|
||||||
alt="Property Thumbnail"
|
|
||||||
style={{
|
|
||||||
marginTop: "0px",
|
|
||||||
maxWidth: "500px",
|
|
||||||
maxHeight: "500px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<img
|
|
||||||
src={propertydummy}
|
|
||||||
alt="Default Property Thumbnail"
|
|
||||||
style={{
|
|
||||||
marginTop: "0px",
|
|
||||||
maxWidth: "500px",
|
|
||||||
maxHeight: "500px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<div className="label-stock border">
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
color: "#fda417",
|
|
||||||
fontSize: "30px",
|
|
||||||
padding: "10px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Total Funding Amount:{" "}
|
|
||||||
<span style={{ color: "#000000", fontSize: "25px" }}>
|
|
||||||
<span
|
|
||||||
className="fa fa-dollar"
|
|
||||||
style={{ color: "#F74B02" }}
|
|
||||||
/>{" "}
|
|
||||||
{selectedProperty.totalCoststoBuyAtoB}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
color: "#fda417",
|
|
||||||
fontSize: "30px",
|
|
||||||
padding: "10px",
|
|
||||||
fontWeight: "normal",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Net profit:{" "}
|
|
||||||
<span style={{ color: "#000000", fontSize: "25px" }}>
|
|
||||||
<span
|
|
||||||
className="fa fa-dollar"
|
|
||||||
style={{ color: "#F74B02" }}
|
|
||||||
/>{" "}
|
|
||||||
{selectedProperty.NetProfit}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br />
|
<ul className="nav nav-tabs" role="tablist">
|
||||||
{/* "Willing to Invest/Fund" Button and Conditional Messages */}
|
<li
|
||||||
<button
|
role="presentation"
|
||||||
className="btn btn-primary back"
|
className={activeTab === "propertydetails" ? "active tab" : "tab"}
|
||||||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
>
|
||||||
disabled={isOwner || !isLoggedIn}
|
<a onClick={() => setActiveTab("propertydetails")} role="tab">
|
||||||
onClick={isOwner || !isLoggedIn ? null : handleShowModal} // Show modal only if not owner or logged in
|
Property Details
|
||||||
>
|
</a>
|
||||||
<span
|
</li>
|
||||||
style={{
|
<li
|
||||||
fontSize: "25px",
|
role="presentation"
|
||||||
fontWeight: "normal",
|
className={activeTab === "Funding Details" ? "active tab" : "tab"}
|
||||||
}}
|
>
|
||||||
>
|
<a onClick={() => setActiveTab("Funding Details")} role="tab">
|
||||||
Willing to Invest/Fund
|
Funding Details
|
||||||
</span>{" "}
|
</a>
|
||||||
</button>
|
</li>
|
||||||
{isOwner && (
|
|
||||||
<span style={{ color: "red", marginTop: "10px" }}>
|
|
||||||
You cannot invest on your property.
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{!isLoggedIn && (
|
|
||||||
<span style={{ color: "red", marginTop: "10px" }}>
|
|
||||||
Please login to submit.
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-md-7 mt-3">
|
<li
|
||||||
<div className="product-view">
|
role="presentation"
|
||||||
<h4
|
className={activeTab === "Accounting" ? "active tab" : "tab"}
|
||||||
className="product-name"
|
>
|
||||||
style={{ color: "#fda417", fontSize: "25px" }}
|
<a onClick={() => setActiveTab("Accounting")} role="tab">
|
||||||
>
|
Accounting
|
||||||
{selectedProperty.address}
|
</a>
|
||||||
<label className="label-stock bg-success">
|
</li>
|
||||||
Verified Property
|
</ul>
|
||||||
</label>
|
|
||||||
</h4>
|
|
||||||
<hr />
|
|
||||||
<p className="product-path">
|
|
||||||
<span style={{ color: "#fda417", fontSize: "15px" }}>
|
|
||||||
City:{" "}
|
|
||||||
</span>{" "}
|
|
||||||
{selectedProperty.city}
|
|
||||||
{" "} /{" "}
|
|
||||||
{" "}
|
|
||||||
{" "}
|
|
||||||
<span style={{ color: "#fda417", fontSize: "15px" }}>
|
|
||||||
County:{" "}
|
|
||||||
</span>{" "}
|
|
||||||
{selectedProperty.county} {" "}/{" "}
|
|
||||||
{" "}
|
|
||||||
<span style={{ color: "#fda417", fontSize: "15px" }}>
|
|
||||||
State:{" "}
|
|
||||||
</span>{" "}
|
|
||||||
{selectedProperty.state} {" "}/ {" "}
|
|
||||||
{" "}
|
|
||||||
<span style={{ color: "#fda417", fontSize: "15px" }}>
|
|
||||||
Zipcode:{" "}
|
|
||||||
</span>{" "}
|
|
||||||
{selectedProperty.zip}
|
|
||||||
{" "}
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<span
|
|
||||||
className="selling-price"
|
|
||||||
style={{ color: "#fda417", fontSize: "15px" }}
|
|
||||||
>
|
|
||||||
Total Living Square Foot:{" "}
|
|
||||||
</span>
|
|
||||||
{selectedProperty.totallivingsqft}
|
|
||||||
<p></p>
|
|
||||||
<span
|
|
||||||
className=""
|
|
||||||
style={{ color: "#fda417", fontSize: "15px" }}
|
|
||||||
>
|
|
||||||
Cost per Square Foot:{" "}
|
|
||||||
</span>
|
|
||||||
${selectedProperty.costpersqft}/sqft
|
|
||||||
<p></p>
|
|
||||||
<span
|
|
||||||
className=""
|
|
||||||
style={{ color: "#fda417", fontSize: "15px" }}
|
|
||||||
>
|
|
||||||
Year Built:{" "}
|
|
||||||
</span>
|
|
||||||
{selectedProperty.yearBuild}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-3 card bg-white label-stock border">
|
<div className="tab-content">
|
||||||
<h5
|
{activeTab === "propertydetails" && (
|
||||||
className="mb-0"
|
<div
|
||||||
style={{ color: "#fda417", fontSize: "15px" }}
|
role="tabpanel"
|
||||||
>
|
className="card container tab-pane active col-12"
|
||||||
Legal Description
|
>
|
||||||
</h5>
|
<div className="container col-12">
|
||||||
<span>
|
{loading ? (
|
||||||
{selectedProperty.legal
|
<div className="loader">Loading...</div> // Loader
|
||||||
? selectedProperty.legal
|
) : selectedProperty ? (
|
||||||
: "No data available"}
|
<div className="py-3 py-md-5 bg-light">
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12 mt-3">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-header bg-white">
|
<div className="card-header bg-white">
|
||||||
<h4
|
<div className="row">
|
||||||
className="product-name"
|
<div className="col-md-5 mt-3">
|
||||||
style={{ color: "#fda417", fontSize: "25px" }}
|
<div>
|
||||||
>
|
{selectedProperty.images &&
|
||||||
Description
|
selectedProperty.images[0] ? (
|
||||||
</h4>
|
<img
|
||||||
</div>
|
src={
|
||||||
<div className="card-body">
|
selectedProperty.images[0].file ||
|
||||||
<p>
|
propertydummy
|
||||||
Lorem Ipsum is simply dummy text of the printing and
|
}
|
||||||
typesetting industry. Lorem Ipsum has been the
|
alt="Property Thumbnail"
|
||||||
industry's standard dummy text ever since the 1500s,
|
style={{
|
||||||
when an unknown printer took a galley of type and
|
marginTop: "0px",
|
||||||
scrambled it to make a type specimen book. It has
|
maxWidth: "400px",
|
||||||
survived not only five centuries, but also the leap into
|
maxHeight: "400px",
|
||||||
electronic typesetting, remaining essentially unchanged.
|
}}
|
||||||
It was popularised in the 1960s with the release of
|
/>
|
||||||
Letraset sheets containing Lorem Ipsum passages, and
|
) : (
|
||||||
more recently with desktop publishing software like
|
<img
|
||||||
Aldus PageMaker including versions of Lorem Ipsum.
|
src={propertydummy}
|
||||||
</p>
|
alt="Default Property Thumbnail"
|
||||||
|
style={{
|
||||||
|
marginTop: "0px",
|
||||||
|
maxWidth: "400px",
|
||||||
|
maxHeight: "400px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* <img
|
||||||
|
src={selectedProperty.images?.[0]?.file || propertydummy}
|
||||||
|
alt="Property Thumbnail"
|
||||||
|
style={{ marginTop: "0px", maxWidth: "400px", maxHeight: "400px" }}
|
||||||
|
loading="lazy"
|
||||||
|
/> */}
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div className="label-stock border">
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#fda417",
|
||||||
|
fontSize: "30px",
|
||||||
|
padding: "10px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Funding Required:{" "}
|
||||||
|
<span
|
||||||
|
style={{ color: "#000000", fontSize: "25px" }}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="fa fa-dollar"
|
||||||
|
style={{ color: "#F74B02" }}
|
||||||
|
/>{" "}
|
||||||
|
{selectedProperty.totalCoststoBuyAtoB}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "#fda417",
|
||||||
|
fontSize: "30px",
|
||||||
|
padding: "10px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Net profit:{" "}
|
||||||
|
<span
|
||||||
|
style={{ color: "#000000", fontSize: "25px" }}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="fa fa-dollar"
|
||||||
|
style={{ color: "#F74B02" }}
|
||||||
|
/>{" "}
|
||||||
|
{selectedProperty.NetProfit}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
{/* "Willing to Invest/Fund" Button and Conditional Messages */}
|
||||||
|
<button
|
||||||
|
className="btn btn-primary back"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#fda417",
|
||||||
|
border: "#fda417",
|
||||||
|
}}
|
||||||
|
disabled={isOwner || !isLoggedIn}
|
||||||
|
onClick={
|
||||||
|
isOwner || !isLoggedIn ? null : handleShowModal
|
||||||
|
} // Show modal only if not owner or logged in
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: "25px",
|
||||||
|
fontWeight: "normal",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Willing to Invest/Fund
|
||||||
|
</span>{" "}
|
||||||
|
</button>
|
||||||
|
{isOwner && (
|
||||||
|
<span style={{ color: "red", marginTop: "10px" }}>
|
||||||
|
You cannot invest in your own property.
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{!isLoggedIn && (
|
||||||
|
<span style={{ color: "red", marginTop: "10px" }}>
|
||||||
|
Please login to invest.
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-7 mt-3">
|
||||||
|
<div className="product-view">
|
||||||
|
<h4
|
||||||
|
className="product-name"
|
||||||
|
style={{ color: "#fda417", fontSize: "25px" }}
|
||||||
|
>
|
||||||
|
{selectedProperty.address}
|
||||||
|
<label className="label-stock bg-success">
|
||||||
|
Verified Property
|
||||||
|
</label>
|
||||||
|
</h4>
|
||||||
|
<hr />
|
||||||
|
<p className="product-path">
|
||||||
|
<span
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
City:{" "}
|
||||||
|
</span>{" "}
|
||||||
|
{selectedProperty.city}
|
||||||
|
{" "} /{" "}
|
||||||
|
{" "}
|
||||||
|
{" "}
|
||||||
|
<span
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
County:{" "}
|
||||||
|
</span>{" "}
|
||||||
|
{selectedProperty.county} {" "}/{" "}
|
||||||
|
{" "}
|
||||||
|
<span
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
State:{" "}
|
||||||
|
</span>{" "}
|
||||||
|
{selectedProperty.state} {" "}/ {" "}
|
||||||
|
{" "}
|
||||||
|
<span
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
Zipcode:{" "}
|
||||||
|
</span>{" "}
|
||||||
|
{selectedProperty.zip}
|
||||||
|
{" "}
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
className="selling-price"
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
Total Living Square Foot:{" "}
|
||||||
|
</span>
|
||||||
|
{selectedProperty.totallivingsqft}
|
||||||
|
<p></p>
|
||||||
|
<span
|
||||||
|
className=""
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
Cost per Square Foot:{" "}
|
||||||
|
</span>
|
||||||
|
${selectedProperty.costpersqft}/sqft
|
||||||
|
<p></p>
|
||||||
|
<span
|
||||||
|
className=""
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
Year Built:{" "}
|
||||||
|
</span>
|
||||||
|
{selectedProperty.yearBuild}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-3 card bg-white label-stock border">
|
||||||
|
<h5
|
||||||
|
className="mb-0"
|
||||||
|
style={{ color: "#fda417", fontSize: "15px" }}
|
||||||
|
>
|
||||||
|
Legal Description
|
||||||
|
</h5>
|
||||||
|
<span>
|
||||||
|
{selectedProperty.legal
|
||||||
|
? selectedProperty.legal
|
||||||
|
: "No data available"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-header bg-white">
|
||||||
|
<h4
|
||||||
|
className="product-name"
|
||||||
|
style={{ color: "#fda417", fontSize: "25px" }}
|
||||||
|
>
|
||||||
|
Description
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<p>
|
||||||
|
Lorem Ipsum is simply dummy text of the printing
|
||||||
|
and typesetting industry. Lorem Ipsum has been
|
||||||
|
the industry's standard dummy text ever since
|
||||||
|
the 1500s, when an unknown printer took a galley
|
||||||
|
of type and scrambled it to make a type specimen
|
||||||
|
book. It has survived not only five centuries,
|
||||||
|
but also the leap into electronic typesetting,
|
||||||
|
remaining essentially unchanged. It was
|
||||||
|
popularised in the 1960s with the release of
|
||||||
|
Letraset sheets containing Lorem Ipsum passages,
|
||||||
|
and more recently with desktop publishing
|
||||||
|
software like Aldus PageMaker including versions
|
||||||
|
of Lorem Ipsum.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : (
|
||||||
|
<p>No property found.</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
) : (
|
|
||||||
<p>No property found.</p>
|
{activeTab === "Funding Details" && (
|
||||||
)}
|
<div>
|
||||||
|
{activeTab === "Funding Details" && (
|
||||||
|
<div className="tab-pane active">
|
||||||
|
{fundDetails ? (
|
||||||
|
<div>
|
||||||
|
<p>Investment Amount: ${fundDetails.investmentAmount}</p>
|
||||||
|
<p>
|
||||||
|
Ownership Percentage: {fundDetails.ownershipPercentage}%
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p>No funding details available.</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === "Accounting" && <div></div>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
{/* Modal for Investment/Funding */}
|
{/* Modal for Investment/Funding */}
|
||||||
|
@ -290,42 +407,25 @@ const PropertyView = () => {
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<Form onSubmit={handleSubmit}>
|
<Form onSubmit={handleSubmit}>
|
||||||
<Form.Group controlId="fundValue">
|
<Form.Group>
|
||||||
<Form.Label>Investment Amount ($)</Form.Label>
|
<Form.Label>Fund Value</Form.Label>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="number"
|
type="number"
|
||||||
placeholder="Enter amount"
|
|
||||||
value={fundValue}
|
value={fundValue}
|
||||||
onChange={(e) => setFundValue(e.target.value)}
|
onChange={(e) => setFundValue(e.target.value)}
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group controlId="fundPercentage">
|
<Form.Group>
|
||||||
<Form.Label>Ownership Percentage (%)</Form.Label>
|
<Form.Label>Fund Percentage</Form.Label>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="number"
|
type="number"
|
||||||
placeholder="Enter percentage"
|
|
||||||
value={fundPercentage}
|
value={fundPercentage}
|
||||||
onChange={(e) => setFundPercentage(e.target.value)}
|
onChange={(e) => setFundPercentage(e.target.value)}
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Button
|
<Button variant="primary" type="submit">
|
||||||
variant="primary"
|
|
||||||
type="submit"
|
|
||||||
style={{ backgroundColor: "#fda417", border: "#fda417" }}
|
|
||||||
>
|
|
||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
{" "}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="primary"
|
|
||||||
onClick={handleCloseModal}
|
|
||||||
style={{ backgroundColor: "#d80b0b", border: "#d80b0b" }}
|
|
||||||
>
|
|
||||||
close
|
|
||||||
</Button>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -26,7 +26,8 @@ export const fetchUserProperties = (userId, page, limit) => API.get( `/propertie
|
||||||
export const fetchPropertyById = (id) => API.get(`/properties/${id}`, id);
|
export const fetchPropertyById = (id) => API.get(`/properties/${id}`, id);
|
||||||
export const updateProperty = (id, propertyData) => API.put(`/properties/${id}`, propertyData);
|
export const updateProperty = (id, propertyData) => API.put(`/properties/${id}`, propertyData);
|
||||||
export const showUser = (userId) => API.get(`/users/${userId}`);
|
export const showUser = (userId) => API.get(`/users/${userId}`);
|
||||||
export const submitFundDetails = (fundDetails) => API.post(`/fundDetails`, fundDetails);
|
export const submitFundDetails = (fundDetailsArray) => API.post(`/fundDetails`, fundDetailsArray);
|
||||||
|
export const getFundDetailsById = (fundDetails) => API.post(`/fundDetails`, fundDetails);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ export const updateProperty = createAsyncThunk(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// export const getProperties = createAsyncThunk("property/getProperties", async () => {
|
// export const getProperties = createAsyncThunk("property/getProperties", async () => {
|
||||||
// const response = await axios.get(`${import.meta.env.VITE_REACT_APP_SECRET}/properties`); // Backend endpoint
|
// const response = await axios.get(`${import.meta.env.VITE_REACT_APP_SECRET}/properties`); // Backend endpoint
|
||||||
// return response.data;
|
// return response.data;
|
||||||
|
@ -164,6 +168,8 @@ const propertySlice = createSlice({
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
state.error = action.error.message;
|
state.error = action.error.message;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue