PlotTrade is a full-stack real estate marketplace for browsing, filtering, and managing property listings. It supports buyer and seller accounts, protected listing workflows, Google sign-in, and image uploads for property media.
- User registration, sign-in, and Google authentication
- Buyer and seller role selection with route protection
- Create, update, delete, and browse property listings
- Advanced listing search with filters for price, type, offer, parking, and furnishing
- User profile management, including avatar updates
- Responsive UI built with React, Tailwind CSS, and Swiper
- MongoDB-backed persistence with JWT cookie-based authentication
- Frontend: React 19, Vite, React Router, Redux Toolkit, Tailwind CSS, Swiper, Axios
- Backend: Node.js, Express, MongoDB, Mongoose, JWT, bcryptjs, cookie-parser, Morgan
- Authentication and media: Firebase, Cloudinary
- Package manager: pnpm
PlotTrade uses a simple client-server architecture:
- The React client runs in Vite and proxies API requests to the backend during development.
- The Express server exposes REST endpoints under
/api/*and handles authentication, users, and listings. - MongoDB stores user and listing documents through Mongoose models.
- Authenticated requests rely on an HTTP-only
access_tokencookie containing a JWT. - Firebase handles Google authentication, while Cloudinary is used for image uploads.
- Node.js 18 or later
- pnpm
- MongoDB connection string
- Firebase project credentials
- Cloudinary upload URL
git clone https://github.com/zaidy-mughal/Plottrade.git
cd PlottradeInstall the client and server dependencies separately:
cd client
pnpm install
cd ../server
pnpm installCreate a .env file in the client/ directory and a .env file in the server/ directory using the variable lists below.
cd server
pnpm devThe API runs on http://localhost:3000.
cd client
pnpm devThe client runs on Vite, and API calls are proxied to the backend during development.
VITE_FIREBASE_API_KEY=
VITE_FIREBASE_APP_ID=
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_PROJECT_ID=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_CLOUDINARY_URL=DB_CONNECTION_STRING=
JWT_SECRET=POST /api/auth/signup- Create a new user accountPOST /api/auth/signin- Sign in with email, password, and rolePOST /api/auth/google- Sign in or register with GoogleGET /api/auth/signout- Clear the auth cookie and sign out
POST /api/listings/create- Create a listing for a seller accountDELETE /api/listings/delete/:id- Delete a listing owned by the current sellerPATCH /api/listings/update/:id- Update a listing owned by the current sellerGET /api/listings/me- Fetch listings created by the current sellerGET /api/listings/:id- Fetch a single listing by IDGET /api/listings- Fetch listings with search, filter, pagination, and sorting support
POST /api/user/update/:id- Update the current user profileDELETE /api/user/delete/:id- Delete the current user accountGET /api/user/:id- Fetch user profile detailsPUT /api/user/update/avatar/:id- Update the current user avatar
Plottrade/
├── client/
│ ├── src/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── redux/
│ │ ├── App.jsx
│ │ └── main.jsx
│ ├── firebaseConfig.js
│ ├── vite.config.js
│ └── package.json
└── server/
├── controllers/
├── models/
├── routes/
├── utils/
├── index.js
└── package.json
| Field | Type | Notes |
|---|---|---|
username |
String | Required, unique |
email |
String | Required, unique |
password |
String | Required, hashed before storage |
avatar |
String | Optional, defaults to a placeholder image |
role |
String | Required, enum: buyer or seller |
createdAt |
Date | Added automatically by Mongoose timestamps |
updatedAt |
Date | Added automatically by Mongoose timestamps |
| Field | Type | Notes |
|---|---|---|
name |
String | Required |
description |
String | Required |
address |
String | Required |
regularPrice |
Number | Required |
discountPrice |
Number | Required |
bathrooms |
Number | Required |
bedrooms |
Number | Required |
furnished |
Boolean | Required |
parking |
Boolean | Required |
type |
String | Required, typically sale or rent |
offer |
Boolean | Required |
imageUrls |
Array | Required list of listing images |
userRef |
String | Required owner reference |
createdAt |
Date | Added automatically by Mongoose timestamps |
updatedAt |
Date | Added automatically by Mongoose timestamps |
- Add booking functionality so users can schedule property visits or reservation requests
- Add a notification system for booking updates, listing changes, and account activity
No license has been specified yet. Add one if you plan to share or publish the project publicly.
- Author: Zaidy Mughal
- GitHub: zaidy-mughal