A full-stack guest house management application for guest registration, room booking, enquiries, and back-office management. Built with React/Vite on the frontend and Express on the backend.
- Frontend: React + Vite
- Backend: Express
- Build: Vite + esbuild
- Node.js v18+
- npm
npm installnpm run devThe app is available at http://localhost:3000.
This project uses Prisma with a database configured through prisma/schema.prisma.
Create or update .env with a valid Prisma connection string, for example:
DATABASE_URL="mysql://root:your_password@127.0.0.1:3306/dream_pension"npx prisma db pushOr, if you want to create a migration history:
npx prisma migrate dev --name initnpx tsx prisma/seed.tsIf you want to reset and reseed the database from scratch:
npx prisma migrate reset --forcenpm install
npx vite buildnpm install
npx vite buildThis outputs optimized frontend files to dist/.
npx serve -s dist -l 5173npx serve -s dist -l 5173or:
npx http-server dist -p 5173npx http-server dist -p 5173npm installnpm run buildThis builds the frontend into dist/ and the backend into dist/server.cjs.
If you have an ecosystem file configured, start all processes with:
pm2 start ecosystem.config.cjsIf you are starting the built backend directly, use:
NODE_ENV=production PORT=3000 pm2 start node --name dream-hotel-backend -- dist/server.cjs$env:NODE_ENV='production'; $env:PORT='3000'; pm2 start node --name dream-hotel-backend -- dist/server.cjspm2 statuspm2 logs dream-hotel-backendpm2 restart dream-hotel-backend
pm2 stop dream-hotel-backend
pm2 delete dream-hotel-backendpm2 save
pm2 startupUse Nginx to serve static frontend files from dist/ and proxy /api/ to the backend.
server {
listen 80;
server_name your.domain;
root /path/to/project/dist;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
try_files $uri $uri/ /index.html;
}
}Reload Nginx:
sudo nginx -t
sudo systemctl reload nginx || sudo nginx -s reloadnpm run buildbuilds both frontend and backend for production.- Make sure production environment variables are set before starting the server.
- Use a process manager such as PM2 or systemd in production.
This project uses Cloudinary for gallery image uploads and runtime optimization.
Set these for the backend to upload images:
CLOUDINARY_URLor all three of:CLOUDINARY_CLOUD_NAMECLOUDINARY_API_KEYCLOUDINARY_API_SECRET
If credentials are not configured, gallery uploads will be disabled.
- Admin uploads are handled by
backend/modules/gallery/gallery.controller.ts. - Uploaded files are streamed to Cloudinary using the
cloudinarypackage. - Uploaded images are stored under the
dream_hotel_galleryfolder in Cloudinary. - The backend stores the secure Cloudinary URL in the gallery record.
The frontend optimizes Cloudinary image URLs at render time using src/features/gallery/cloudinary.ts.
The helper supports options like:
widthcropgravityqualitydprformat
It creates URLs with Cloudinary transformations such as f_auto, q_auto, and dpr_auto.
Example backend env values:
CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>Example runtime URL optimization:
import { optimizeCloudinaryUrl } from "./features/gallery/cloudinary";
const optimizedUrl = optimizeCloudinaryUrl(image.url, {
width: 600,
crop: "fill",
gravity: "auto",
quality: "auto",
dpr: "auto",
format: "auto",
});This is used in gallery components such as GalleryCard and GalleryLightbox.