Open In App

Property Listing Platform using Node and ExpressJS

Last Updated : 07 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

This tutorial can help you build a foundational understanding of the backend development. NodeJS and ExpressJS are used to build the backend infrastructure of the website and ReactJS is used for the front end of the project. With this project, you can learn essential concepts and best practices for building modern web applications.

Output Preview: Let us have a look at how the final output will look like.

Screenshot-2024-03-05-103937

Final Output

Prerequisites:

Approach to create Property List App:

  • Initialize the node project and install necessary dependencies.
  • Set up the express server.
  • Create react app and design it accordingly.
  • Use cors for cross-domain communication.

Steps to Create NodeJS App and Installing Module:

Step 1: Create a new directory named backend.

mkdir backend
cd backend

Step 2: Create a server using the following command.

npm init -y

Step 3: Install necessary dependencies using the following command:

npm install express cors

Project Structure:

Screenshot-2024-02-29-102700

backend structure

The updated dependencies in package.json file of backend will look like:

"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2"
}

Example: Below is an example of creating a server of property listing platform.

Javascript




// index.js
const express = require('express');
const cors = require('cors');
 
const app = express();
const port = 5000;
 
app.use(cors());
 
const propertySchema = {
    name: String,
    description: String,
    numberOfRooms: Number,
    washroom: Number,
    kitchen: Boolean,
    hall: Boolean,
    amenities: [String]
};
 
 
 
// Temporary storage for properties
let properties = [
    {
        id: 1,
        name: "Luxury Beachfront Villa",
        location: "Malibu, California",
        room: 7,
        price: 1500000,
        amenities: ["Private Beach Access", "Infinity Pool", "Home Theater"]
    },
    {
        id: 2,
        name: "Charming Cottage",
        location: "Cotswolds, England",
        room: 3,
        price: 400000,
        amenities: ["Fireplace", "Garden", "Country Views"]
    },
    {
        id: 3,
        name: "Modern Downtown Loft",
        location: "New York City, New York",
        room: 2,
        price: 800000,
        amenities: ["City Views", "Gym", "Concierge Service"]
    },
    {
        id: 4,
        name: "Rustic Mountain Cabin",
        location: "Aspen, Colorado",
        room: 4,
        price: 600000,
        amenities: ["Hot Tub", "Ski-In/Ski-Out Access", "Wood-Burning Fireplace"]
    },
    {
        id: 5,
        name: "Paris Apartment",
        location: "Paris, France",
        room: 6,
        price: 2500000,
        amenities: ["Terrace", "Panoramic City Views", "24/7 Security"]
    },
    {
        id: 6,
        name: "Secluded Lakeside Retreat",
        location: "Lake District, England",
        room: 5,
        price: 1000000,
        amenities: ["Private Dock", "Boathouse", "Tranquil Surroundings"]
    }
];
 
// Route to list properties
app.get('/properties', (req, res) => {
    res.json(properties);
});
 
// Route to create a new property
app.post('/properties', (req, res) => {
    const newProperty = req.body;
    properties.push(newProperty);
    res.status(201).json({
        message: 'Property created successfully',
        property: newProperty
    });
});
 
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});


Start the server with the following command.

node index.js

Steps to Create the Frontend App and Installing Module:

Step 1: Create the frontend repository named client in the main repository.

mkdir client
cd client

Step 2: Create React project using following command.

npx create-react-app .

Project Structure:

Screenshot-2024-02-29-103451

frontend project structure

Example: Create the files according to the project structure and write the following code.

CSS




.home-container {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
   
  .filter {
    margin-bottom: 20px;
  }
   
  .filter label {
    margin-right: 10px;
  }
   
  .filter input {
    margin-right: 10px;
    padding: 5px;
    border: 1px solid #ccc;
  }
   
  .filter button {
    padding: 5px 10px;
    background-color: #007bff;
    color: #fff;
    border: none;
    cursor: pointer;
  }
   
  .filter button:hover {
    background-color: #0056b3;
  }
   
  .property-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    grid-gap: 20px;
  }
   
  .property-list p {
    font-style: italic;
    color: #888;
  }
  .navbar {
    background-color: #333334;
    color: #fff;
    padding: 10px 20px;
    margin-bottom: 20px;
  }
   
  .logo {
    font-size: 1.5rem;
    font-weight: bold;
  }
.property-card {
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 5px;
  margin: 10px;
}
 
.property-image {
  display: inline-block;
  width: 200px;
}
 
.property-image img {
  width: 100%;
  height: auto;
}
 
.property-details {
  display: inline-block;
  vertical-align: top;
  margin-left: 10px;
  padding: 10px;
}
 
.property-details h2 {
  margin-top: 0;
}
 
.property-details p {
  margin: 5px 0;
}


Javascript




// App.js
import React from 'react';
import Navbar from './Navbar.js';
import Home from './Home';
import './index.css';
 
function App() {
    return (
        <div className="App">
            <Navbar />
            <Home />
        </div>
    );
}
 
export default App;


Javascript




import React, { useState, useEffect } from 'react';
import PropertyCard from './PropertyCard';
import './index.css'; // Import CSS file for styling
 
function Home() {
  const [properties, setProperties] = useState([]);
  const [filteredProperties, setFilteredProperties] = useState([]);
  const [filters, setFilters] = useState({
    minPrice: '',
    maxPrice: '',
    minRooms: '',
    maxRooms: ''
  });
 
  useEffect(() => {
    // Fetch properties from the backend
      .then(response => response.json())
      .then(data => {
        setProperties(data);
        setFilteredProperties(data); // Initialize filtered properties with all properties
      })
      .catch(error => console.error('Error fetching properties:', error));
  }, []);
 
  const applyFilters = () => {
    let filtered = properties;
 
    if (filters.minPrice !== '' && filters.maxPrice !== '') {
      filtered = filtered.filter(property => property.price >= filters.minPrice && property.price <= filters.maxPrice);
    }
 
    if (filters.minRooms !== '' && filters.maxRooms !== '') {
      filtered = filtered.filter(property => property.room >= filters.minRooms && property.room <= filters.maxRooms);
    }
 
    setFilteredProperties(filtered);
  };
 
  const handleFilterChange = event => {
    const { name, value } = event.target;
    setFilters({ ...filters, [name]: value });
  };
 
  return (
    <div className="home-container">
      <div className="filter">
        <label>Minimum Price:</label>
        <input type="number" name="minPrice" value={filters.minPrice} onChange={handleFilterChange} />
        <label>Maximum Price:</label>
        <input type="number" name="maxPrice" value={filters.maxPrice} onChange={handleFilterChange} />
        <label>Minimum Rooms:</label>
        <input type="number" name="minRooms" value={filters.minRooms} onChange={handleFilterChange} />
        <label>Maximum Rooms:</label>
        <input type="number" name="maxRooms" value={filters.maxRooms} onChange={handleFilterChange} />
        <button onClick={applyFilters}>Apply</button>
      </div>
      <div className='parent-property'>
        <div className="property-list">
          {filteredProperties.length > 0 ? (
            filteredProperties.map(property => (
              <PropertyCard key={property.id} property={property} />
            ))
          ) : (
            <p>No properties found</p>
          )}
        </div>
      </div>
    </div>
  );
}
 
export default Home;


Javascript




import React from 'react';
 
function PropertyCard({ property }) {
    const { id, name, location, room, img, price, amenities } = property;
 
    return (
        <div className="property-card">
            <div className="property-image">
                <img src={`${img}`} alt={name} />
            </div>
            <div className="property-details">
                <h2>{name}</h2>
                <p>Location: {location}</p>
                <p>Rooms: {room}</p>
                <p>Price: ${price}</p>
                <p>Amenities: {amenities.join(', ')}</p>
            </div>
        </div>
    );
}
 
export default PropertyCard;


Javascript




import React, {
    useState,
    useEffect
} from 'react';
import PropertyCard from './PropertyCard.js';
import './index.css';
 
function Home() {
    const [properties, setProperties] = useState([]);
    const [filteredProperties, setFilteredProperties] = useState([]);
    const [filters, setFilters] = useState({
        minPrice: '',
        maxPrice: '',
        minRooms: '',
        maxRooms: ''
    });
 
    useEffect(() => {
        // Fetch properties from the backend
        fetch('http://localhost:5000/properties')
            .then(response => response.json())
            .then(data => {
                setProperties(data);
                setFilteredProperties(data);
            })
            .catch(error =>
                console.error(
                    'Error fetching properties:', error));
    }, []);
 
    const applyFilters = () => {
        let filtered = properties;
 
        if (filters.minPrice !== '' && filters.maxPrice !== '') {
            filtered = filtered.filter(
                property => property.price >= filters.minPrice &&
                    property.price <= filters.maxPrice);
        }
 
        if (filters.minRooms !== '' && filters.maxRooms !== '') {
            filtered = filtered.filter(
                property => property.room >= filters.minRooms &&
                    property.room <= filters.maxRooms);
        }
 
        setFilteredProperties(filtered);
    };
 
    const handleFilterChange = event => {
        const { name, value } = event.target;
        setFilters({ ...filters, [name]: value });
    };
 
    return (
        <div className="home-container">
            <div className="filter">
                <label>Minimum Price:</label>
                <input type="number" name="minPrice"
                    value={filters.minPrice} onChange={handleFilterChange} />
                <label>Maximum Price:</label>
                <input type="number" name="maxPrice"
                    value={filters.maxPrice} onChange={handleFilterChange} />
                <label>Minimum Rooms:</label>
                <input type="number" name="minRooms"
                    value={filters.minRooms} onChange={handleFilterChange} />
                <label>Maximum Rooms:</label>
                <input type="number" name="maxRooms"
                    value={filters.maxRooms} onChange={handleFilterChange} />
                <button onClick={applyFilters}>Apply</button>
            </div>
            <div className='parent-property'>
                <div className="property-list">
                    {filteredProperties.length > 0 ? (
                        filteredProperties.map(property => (
                            <PropertyCard key={property.id}
                                property={property} />
                        ))
                    ) : (
                        <p>No properties found</p>
                    )}
                </div>
            </div>
        </div>
    );
}
 
export default Home;


Start the project using the given command.

npm start

Output:

gfg67

Output



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads