Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🏨 StayBook β€” Hotel Booking App (Booking.com Replica)

A full-stack hotel booking web application replicating Booking.com. Stack: HTML + CSS + JS (Frontend) Β· Node.js + Express + MongoDB + JWT + Nodemailer (Backend)


πŸ“ PROJECT STRUCTURE

hotel-booking/
β”œβ”€β”€ index.html          ← Complete frontend (single file SPA)
β”œβ”€β”€ server.js           ← Node.js + Express backend
β”œβ”€β”€ package.json        ← Dependencies
β”œβ”€β”€ .env.example        ← Environment variable template
β”œβ”€β”€ .env                ← Your secrets (never commit this!)
β”œβ”€β”€ .gitignore
└── README.md

βœ… STEP 1 β€” INSTALL PREREQUISITES

Make sure you have these installed on your computer:

Install Node.js (v18+)

# Check if installed
node --version
npm --version

# If not installed, download from:
# https://nodejs.org/en/download

Install MongoDB (Local)

# Option A: Install MongoDB Community locally
# https://www.mongodb.com/try/download/community

# Option B (recommended for beginners): Use MongoDB Atlas FREE cloud
# https://www.mongodb.com/cloud/atlas/register
# β†’ Create free cluster β†’ Get connection string β†’ paste in .env

βœ… STEP 2 β€” SETUP THE PROJECT

# 1. Clone or download the project folder
cd hotel-booking

# 2. Install all dependencies
npm install

# 3. Create your .env file from the template
cp .env.example .env

# 4. Open .env in any text editor and fill in:
#    MONGO_URI  β†’ your MongoDB connection string
#    JWT_SECRET β†’ any long random string (e.g. "abc123xyz789secretkey")
#    EMAIL_USER β†’ your Gmail address
#    EMAIL_PASS β†’ Gmail App Password (see Step 3)

βœ… STEP 3 β€” SETUP GMAIL FOR CONFIRMATION EMAILS

To send real booking confirmation emails:

  1. Go to your Google Account β†’ Security β†’ 2-Step Verification β†’ Turn ON
  2. Then go to: https://myaccount.google.com/apppasswords
  3. Create an App Password for "Mail"
  4. Copy the 16-character password
  5. Put it in .env as EMAIL_PASS=xxxx xxxx xxxx xxxx

βœ… STEP 4 β€” RUN THE APP LOCALLY

# Development mode (auto-restarts on file changes)
npm run dev

# OR production mode
npm start

Then open your browser and go to:

http://localhost:5000

βœ… STEP 5 β€” SEED THE DATABASE WITH HOTELS

After starting the server, open a new terminal and run:

# Add sample hotel data to MongoDB
curl -X POST http://localhost:5000/api/seed

# OR open this URL in your browser:
# http://localhost:5000/api/seed  (change to POST via Postman)

πŸ“‘ API ENDPOINTS

AUTH

Method Endpoint Description Auth Required
POST /api/register Register new user No
POST /api/login Login, returns JWT token No
GET /api/me Get current user info Yes

HOTELS

Method Endpoint Description Auth Required
GET /api/hotels List hotels with filters No
GET /api/hotels/:id Get single hotel details No

Hotel filter query params:

GET /api/hotels?dest=Goa&maxPrice=10000&stars=4,5&score=8&amenities=wifi,pool&dist=2

BOOKINGS

Method Endpoint Description Auth Required
POST /api/bookings Create booking + send email Yes
GET /api/bookings Get user's bookings Yes
DELETE /api/bookings/:id Cancel a booking Yes

Example: Make a Booking (POST /api/bookings)

{
  "hotelId": "65abc123...",
  "hotelName": "The Grand Palace Hotel",
  "roomType": "Deluxe Room",
  "checkIn": "2024-07-15",
  "checkOut": "2024-07-18",
  "guests": "2 adults",
  "price": 5700,
  "totalPrice": 17100,
  "guestName": "Rahul Sharma",
  "guestEmail": "rahul@example.com",
  "guestPhone": "+91 98765 43210",
  "specialReq": "High floor room, late check-in",
  "allergies": "Nut allergy"
}

πŸ”Œ CONNECTING FRONTEND TO BACKEND

The frontend (index.html) currently works standalone with in-memory data. To connect it to the real backend API, replace these functions in index.html:

1. Replace doLogin():

async function doLogin() {
  const email = document.getElementById('loginEmail').value;
  const pass  = document.getElementById('loginPass').value;
  try {
    const res  = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password: pass }),
    });
    const data = await res.json();
    if (!res.ok) { document.getElementById('loginError').style.display='block'; return; }
    localStorage.setItem('token', data.token);
    setLoggedIn(data.user);
    closeModal();
  } catch(e) { console.error(e); }
}

2. Replace doRegister():

async function doRegister() {
  const name  = document.getElementById('regName').value;
  const email = document.getElementById('regEmail').value;
  const pass  = document.getElementById('regPass').value;
  const pass2 = document.getElementById('regPass2').value;
  if (pass !== pass2) { document.getElementById('regError').style.display='block'; return; }
  try {
    const res  = await fetch('/api/register', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name, email, password: pass }),
    });
    const data = await res.json();
    if (!res.ok) { document.getElementById('regError').textContent=data.error; document.getElementById('regError').style.display='block'; return; }
    localStorage.setItem('token', data.token);
    setLoggedIn(data.user);
    closeModal();
  } catch(e) { console.error(e); }
}

3. Replace renderHotels() to fetch from API:

async function renderHotels() {
  const maxPrice = document.getElementById('priceRange').value;
  const dest     = document.getElementById('dest').value;
  const url      = `/api/hotels?dest=${encodeURIComponent(dest)}&maxPrice=${maxPrice}`;
  const res      = await fetch(url);
  const hotels   = await res.json();
  // ... render as before
}

4. Replace confirmBooking() to POST to API:

async function confirmBooking() {
  const token = localStorage.getItem('token');
  const body  = { /* collect all form fields */ };
  const res   = await fetch('/api/bookings', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  // Show confirmation page with data.ref
}

πŸš€ DEPLOYMENT β€” Step by Step

Option A: Deploy on Render.com (FREE β€” Recommended)

# 1. Push your code to GitHub first
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/staybook.git
git push -u origin main

# 2. Go to https://render.com β†’ New β†’ Web Service
# 3. Connect your GitHub repo
# 4. Set these settings:
#    Build Command: npm install
#    Start Command: npm start
#    Environment:   Node
# 5. Add Environment Variables in Render dashboard:
#    MONGO_URI   = mongodb+srv://...  (from MongoDB Atlas)
#    JWT_SECRET  = your_secret_here
#    EMAIL_USER  = your@gmail.com
#    EMAIL_PASS  = your_app_password
#    NODE_ENV    = production
# 6. Click Deploy!
# Your site will be live at: https://staybook.onrender.com

Option B: Deploy on Railway.app

# 1. Install Railway CLI
npm install -g @railway/cli

# 2. Login
railway login

# 3. Create project
railway init

# 4. Add MongoDB plugin in Railway dashboard

# 5. Set environment variables
railway variables set JWT_SECRET=your_secret
railway variables set EMAIL_USER=your@gmail.com
railway variables set EMAIL_PASS=your_app_pass

# 6. Deploy
railway up

# Your site will be live at the URL Railway provides

Option C: Deploy on VPS (DigitalOcean/AWS EC2)

# 1. SSH into your server
ssh root@YOUR_SERVER_IP

# 2. Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# 3. Install MongoDB
sudo apt-get install -y mongodb
sudo systemctl start mongodb

# 4. Install PM2 (keeps app running)
npm install -g pm2

# 5. Clone your repo
git clone https://github.com/YOUR_USERNAME/staybook.git
cd staybook

# 6. Install dependencies
npm install

# 7. Create .env
nano .env
# (paste your environment variables)

# 8. Start with PM2
pm2 start server.js --name staybook
pm2 startup    # auto-start on reboot
pm2 save

# 9. Setup Nginx (reverse proxy)
sudo apt install nginx
sudo nano /etc/nginx/sites-available/staybook

Nginx config:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
sudo ln -s /etc/nginx/sites-available/staybook /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

# 10. Add SSL (free with Let's Encrypt)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com

🐞 COMMON ERRORS & FIXES

Error Fix
ECONNREFUSED on MongoDB Start MongoDB: sudo systemctl start mongodb
Invalid token on API Token expired – login again
Emails not sending Check Gmail App Password, enable 2FA first
Port 5000 in use Kill process: `lsof -ti:5000
Cannot find module Run npm install again
CORS error in browser Make sure backend has cors() middleware

πŸ›  USEFUL COMMANDS

npm run dev          # Start with auto-reload (development)
npm start            # Start normally (production)
npm install          # Install all packages

# MongoDB (local)
mongosh              # Open MongoDB shell
show dbs             # List databases
use staybook         # Switch to staybook db
db.hotels.find()     # View all hotels
db.users.find()      # View all users
db.bookings.find()   # View all bookings

# PM2 (production)
pm2 list             # Show running apps
pm2 logs staybook    # View live logs
pm2 restart staybook # Restart app
pm2 stop staybook    # Stop app

πŸ“Œ GITIGNORE

Create a .gitignore file:

node_modules/
.env
*.log

πŸ“ž SUPPORT

For help, open an issue or contact: support@staybook.com

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages