A full-stack trip planner app where users can create, manage, and track upcoming trips with friends. This app allows users to collaboratively plan itineraries and visualise trip locations on an interactive map and 3D globe.
The project is split into two independent services:
| Folder | Description | Tech |
|---|---|---|
frontend/ |
React SPA (client-side only) | Vite, React, React Router, Tailwind CSS |
backend/ |
REST API server | Express.js, Prisma ORM, Passport.js |
- Frontend: React 19 + Vite, React Router, Tailwind CSS v4, Google Maps (
@react-google-maps/api),react-globe.gl - Backend: Express.js, Prisma 6 (PostgreSQL), Passport.js (Google OAuth), express-session
- Database: PostgreSQL
- Auth: Google OAuth 2.0 via Passport.js with session cookies
- Node.js >= 18 (Node 24 recommended)
- PostgreSQL database
- Google Cloud project with:
- OAuth 2.0 credentials (Client ID + Secret)
- Maps JavaScript API + Geocoding API enabled
# Backend
cd backend
npm install
cp .env.example .env # Fill in your values
# Frontend
cd ../frontend
npm install
cp .env.example .env # Fill in your valuesOption A: Automated setup (recommended)
./setup-postgres.shThis will:
- Install PostgreSQL via Homebrew (if not installed)
- Create database
travellaand usertravella_user - Update
backend/.envwith the connection string - Run Prisma migrations
Option B: Manual setup
See POSTGRES_SETUP.md for detailed instructions including Docker option.
backend/.env (auto-configured by setup script):
DATABASE_URL="postgresql://travella_user:travella_dev_password@localhost:5432/travella?schema=public"
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
GOOGLE_MAPS_API_KEY="your-google-maps-api-key"
SESSION_SECRET="a-random-secret-string"
FRONTEND_URL="http://localhost:5173"
BACKEND_URL="http://localhost:3001"
frontend/.env:
VITE_GOOGLE_MAPS_API_KEY="your-google-maps-api-key"
Option A: Using the start script (recommended)
./start.shThis starts both backend (port 3001) and frontend (port 5173) in the background. Logs are saved to backend.log and frontend.log.
To stop:
./stop.shOption B: Manual start in separate terminals
# Terminal 1 – Backend (port 3001)
cd backend
npm run dev
# Terminal 2 – Frontend (port 5173)
cd frontend
npm run devThe frontend Vite dev server proxies /api requests to http://localhost:3001, so no CORS issues during development.
Open http://localhost:5173 in your browser.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/auth/google |
Initiate Google OAuth login |
| GET | /api/auth/google/callback |
OAuth callback |
| GET | /api/auth/session |
Get current user session |
| POST | /api/auth/logout |
Log out |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/trips |
List user's trips |
| GET | /api/trips/:tripId |
Get trip with details |
| POST | /api/trips |
Create a new trip |
| PUT | /api/trips/:tripId |
Update a trip |
| DELETE | /api/trips/:tripId |
Delete a trip |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/locations |
Add a location |
| PUT | /api/locations/:locationId |
Update a location |
| DELETE | /api/locations/:locationId |
Delete a location |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/globe |
Get all locations with country data |
travella/
├── backend/
│ ├── prisma/ # Prisma schema & migrations
│ ├── src/
│ │ ├── index.ts # Express server entry point
│ │ ├── lib/ # Prisma client, geocode helpers
│ │ ├── middleware/ # Auth middleware, Passport config
│ │ └── routes/ # API route handlers
│ ├── .env.example
│ ├── package.json
│ └── tsconfig.json
├── frontend/
│ ├── public/ # Static assets
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── lib/ # API client, auth context
│ │ ├── pages/ # Page components
│ │ ├── App.tsx # Router & layout
│ │ └── main.tsx # Entry point
│ ├── .env.example
│ ├── package.json
│ ├── vite.config.ts
│ └── tsconfig.json
└── README.md