// ...existing code...
MuseumQuest is an educational web app that showcases museums on an interactive world map. Click a museum to view details, images, and try a short quiz. Users can collect stamps, earn XP, level up, and compete on a leaderboard.
- Interactive map with museum markers
- Museum detail pages with background images and quizzes
- Passport system: stamps, XP, levels, and progress bar
- AI-powered chatbot for museum context
- Leaderboard showing top explorers
- Local backend API that integrates with Firestore
- Frontend: React + Vite (see frontend/package.json)
- Backend: Express (see backend/package.json)
- Firebase Authentication & Firestore (see frontend/src/firebase.js and backend/firebase-admin.js)
- Leaflet for maps (see frontend/src/components/MapComponent.jsx)
- Gemini / Google Generative AI integration in backend (see backend/server.js)
- backend/server.js - main API server and endpoints
- backend/.env.example - example env vars required by backend
- backend/firebase-admin.js - admin SDK init for Firestore
- frontend/package.json - frontend scripts & deps
- frontend/src/main.jsx - app entry
- frontend/src/services/api.js - client API wrappers
- frontend/src/services/firestore.js - Firestore client helpers (see
awardStamp) - frontend/src/data/museums.js - museum metadata and image paths
- frontend/src/data/quizzes.js - quiz question sets
- frontend/src/pages/QuizPage.jsx - quiz UI and image mapping logic
- frontend/src/pages/ChatbotPage.jsx - chatbot UI and AI calls
- frontend/src/data/images/britishmuseum.avif - example museum asset
Backend helpers:
getUserProgress- fetch user progress (server-side)calculateLevel- derive level from XP
Frontend helpers:
awardStamp- award a stamp & update user progress (client-side)getUserProgress- client wrapper to fetch passport
- Node.js 18.x (backend
enginesin backend/package.json) - npm or pnpm
- Firebase project / credentials if using production Firestore (or run with emulator)
-
Backend
- Copy env example:
- cp backend/.env.example backend/.env
- Provide credentials:
- Set
GOOGLE_APPLICATION_CREDENTIALSto your service account JSON path or setFIREBASE_SERVICE_ACCOUNTenv var.
- Set
- Install & run:
- cd backend
- npm install
- npm run dev
- Backend listens on port 5000 by default and exposes endpoints implemented in backend/server.js.
- Copy env example:
-
Frontend
- Install & run:
- cd frontend
- npm install
- npm run dev
- Open the Vite URL printed in the console.
- Install & run:
Check backend/.env.example. Common vars:
- GOOGLE_APPLICATION_CREDENTIALS or FIREBASE_SERVICE_ACCOUNT — Firebase admin credentials (see backend/firebase-admin.js)
- GEMINI_API_KEY — Google Generative AI key used in backend/server.js
- WOLFRAM_API_KEY — optional Wolfram support used in backend routes
The frontend uses Firebase config stored in frontend/src/firebase.js.
Implemented in backend/server.js:
- GET /api/museums — list museums
- GET /api/museums/:id — museum detail
- POST /api/quiz/:museumId — get quiz for a museum
- POST /api/quiz/check — check quiz answers
- POST /api/passport/stamp — award a stamp (server side) — uses
calculateLevel - GET /api/passport/:userId — get a user's passport (
getUserProgress) - GET /api/leaderboard — top users aggregation
- POST /api/ai/ask — AI museum Q&A (Gemini) (see backend/server.js)
- GET /api/wolfram/context/:year — simple historical context
Client wrappers are in frontend/src/services/api.js.
- Images in frontend/src/data/images are imported in pages like QuizPage.jsx and ChatbotPage.jsx. Vite requires imports rather than string file paths — see the image mapping in those files.
- The app handles two data shapes for user progress (legacy vs current). See server-side
getUserProgressand client-sidegetUserProgress. - If using local emulator for Firestore, backend may initialize without credentials (see backend/firebase-admin.js).
There are no tests configured in the repo. Add tests and scripts to backend/package.json and frontend/package.json as needed.
- Fork the repo
- Create a branch
- Open a PR with a description
MIT — see LICENSE
// ...existing code... { changed code } // ...existing code...