Here is a clean, beginner-friendly, copy-paste ready README for your project. It is written like a human, simple, and interviewer-friendly, with examples included.
BookMyYatra is a full-stack hotel booking platform built using Next.js (App Router) for the frontend, Node.js + Express for the backend, and Prisma ORM with PostgreSQL for the database.
This project is structured in a way that works both locally and in production without changing the code.
- Next.js (App Router)
- React
- Tailwind CSS
- Fetch API
- JWT Authentication (LocalStorage)
- Node.js
- Express.js
- Prisma ORM
- PostgreSQL
- JWT
bookmyyatra/
├── app/ # Next.js frontend (App Router)
├── backend/ # Express + Prisma backend
├── public/ # Static assets
├── package.json
└── README.md
app/
├── admin/ # Admin panel pages
│ ├── dashboard/
│ ├── hotels/
│ │ ├── add/
│ │ ├── [id]/edit/
│ └── layout.jsx
│
├── auth/ # Authentication pages
│ ├── login/
│ └── signup/
│
├── components/ # Reusable UI components
│ ├── Navbar.jsx
│ ├── TopHotels.jsx
│ ├── AllRooms.jsx
│ └── ProtectedRoute.jsx
│
├── hotels/ # Public hotel listing
├── RoomDetails/ # Hotel details page
├── Payment/ # Payment page
├── ReviewYourBooking/ # Booking review
│
├── lib/ # Shared frontend logic
│ ├── config.js # Backend URL resolver
│ ├── auth.js # Auth API helpers
│ └── AuthContext.js # Global auth state
│
├── layout.jsx
└── page.jsx
backend/
├── prisma/
│ ├── schema.prisma
│ └── migrations/
│
├── src/
│ ├── controllers/
│ │ ├── authController.js
│ │ └── hotelController.js
│ │
│ ├── middlewares/
│ │ ├── authMiddleware.js
│ │ └── adminMiddleware.js
│ │
│ ├── routes/
│ │ └── routes.js
│ │
│ └── utils/
│ └── generateToken.js
│
├── index.js
└── package.json
NEXT_PUBLIC_BACKEND_LOCAL_URL=http://localhost:5001
NEXT_PUBLIC_BACKEND_PROD_URL=https://bookmyyatra-backend.onrender.comDATABASE_URL=postgresql://username:password@host:5432/dbname
JWT_SECRET=your_jwt_secret
NODE_ENV=development
PORT=5001
FRONTEND_LOCAL_URL=http://localhost:3000
FRONTEND_DEPLOYED_URL=https://akash-jewellers-one.vercel.app/All frontend API calls use one single config file.
export const BACKEND_URL =
process.env.NODE_ENV === "production"
? process.env.NEXT_PUBLIC_BACKEND_PROD_URL
: process.env.NEXT_PUBLIC_BACKEND_LOCAL_URL;This ensures:
- Local development uses localhost
- Production automatically uses Render URL
- No hardcoded URLs anywhere
- Backend returns a JWT
- Token is stored in
localStorage
localStorage.setItem("token", data.token);fetch(`${BACKEND_URL}/api/me`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});const jwt = require("jsonwebtoken");
const authMiddleware = (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.status(401).json({ message: "Unauthorized" });
}
const token = authHeader.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
};
module.exports = authMiddleware;Users have a role field in Prisma.
model User {
id Int @id @default(autoincrement())
name String
email String @unique
role String @default("USER")
}const adminMiddleware = (req, res, next) => {
if (req.user.role !== "ADMIN") {
return res.status(403).json({ message: "Admin access only" });
}
next();
};Admins can:
- View dashboard
- Add hotels
- Edit hotels
- Delete hotels
- Manage listings
Admin pages are automatically shown in the navbar only if the user role is ADMIN.
cd backend
npm install
npm run devBackend runs on:
http://localhost:5001
npm install
npm run devFrontend runs on:
http://localhost:3000
- Hosted on Render
- Uses PostgreSQL (Neon)
- URL:
https://bookmyyatra-backend.onrender.com
- Hosted on Vercel
- Automatically uses production backend URL
- Token missing or expired
- Authorization header not sent
- User not logged in
- Backend URL incorrect
- Backend server not running
- CORS misconfiguration
Errors like:
chrome-extension://... ERR_FILE_NOT_FOUND
are caused by browser extensions and can be safely ignored.
- Booking system
- Payment gateway
- Reviews and ratings
- Email notifications
- Admin analytics dashboard