A full-stack web application for UCI students to discover and explore matcha spots in and around Irvine, CA.
- 🔍 Search & Filter: Search matcha spots by name, location, or description
- ⭐ Ratings & Reviews: View ratings and review counts for each spot
- 🏆 Featured Spots: Highlight your favorite matcha locations
- 💰 Price Range: Filter by price range ($ to $$$$)
- 📍 Location Details: Complete address information for each spot
- 📱 Responsive Design: Beautiful, modern UI that works on all devices
- 🎨 Modern UI: Clean, matcha-themed design with smooth animations
- 👥 User Authentication: Firebase Authentication for user accounts
- 📝 Matcha Feed: Share and discover matcha experiences from the community
- Firebase Authentication: User login/registration
- Cloud Firestore: Database for spots and experiences
- Firebase Storage (optional): For hosting images
- React 19: Modern React with hooks
- Firebase SDK: Firebase client libraries
- React Leaflet: Interactive maps
- CSS3: Custom styling with modern design patterns
MatchaMap/
├── frontend/ # React application
│ ├── public/
│ │ ├── matcha_spots/ # Static image files
│ │ └── MatchaverseLogo.png
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── LandingPage.js
│ │ │ ├── MapView.js
│ │ │ ├── Sidebar.js
│ │ │ ├── FeedPanel.js
│ │ │ ├── AuthModal.js
│ │ │ └── ...
│ │ ├── services/ # Firebase service layer
│ │ │ ├── firebase.js
│ │ │ ├── authFirebase.js
│ │ │ ├── spotsFirebase.js
│ │ │ └── experiencesFirebase.js
│ │ ├── App.js # Main app component
│ │ └── App.css # App styles
│ └── package.json
├── FIRESTORE_SETUP.md # Firestore security rules setup
└── README.md
- Node.js 14+ and npm
- Firebase account (free tier works)
-
Create a Firebase project at https://console.firebase.google.com
-
Enable Authentication:
- Go to Authentication → Sign-in method
- Enable "Email/Password"
-
Create a Firestore database:
- Go to Firestore Database
- Click "Create database"
- Start in "Production mode" (we'll set rules next)
-
Set up Firestore security rules (REQUIRED):
- Go to Firestore Database → Rules tab
- Copy the rules from
FIRESTORE_SETUP.mdor see below - Click "Publish" (critical step!)
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /experiences/{experienceId} { allow read: if true; allow create: if request.auth != null && request.resource.data.userId == request.auth.uid; allow update, delete: if request.auth != null && resource.data.userId == request.auth.uid; } match /spots/{spotId} { allow read: if true; allow write: if false; } } }
-
Get your Firebase config:
- Go to Project settings → General → Your apps
- Click the web icon (
</>) to add a web app - Copy the config values
-
Create
frontend/.envfile:REACT_APP_FIREBASE_API_KEY=YOUR_API_KEY REACT_APP_FIREBASE_AUTH_DOMAIN=YOUR_PROJECT.firebaseapp.com REACT_APP_FIREBASE_PROJECT_ID=YOUR_PROJECT_ID REACT_APP_FIREBASE_APP_ID=YOUR_APP_ID REACT_APP_FIREBASE_MESSAGING_SENDER_ID=YOUR_SENDER_ID REACT_APP_FIREBASE_STORAGE_BUCKET=YOUR_PROJECT.appspot.com
-
Navigate to frontend directory:
cd frontend -
Install dependencies:
npm install
-
Start the React development server:
npm start
The React app will automatically open in your browser at
http://localhost:3000
-
Create the
spotscollection in Firestore:- Go to Firebase Console → Firestore Database
- Click "Start collection"
- Collection ID:
spots - Add documents with the following fields:
name(string)address(string)city(string)state(string)zip_code(string)latitude(number)longitude(number)rating(number, 0-5)review_count(number)description(string)phone(string, optional)website(string, optional)hours(string, optional)price_range(string:$,$$,$$$, or$$$$)is_featured(boolean)imageUrl(string, optional) - Use paths like/matcha_spots/omomo.jpgfor images inpublic/matcha_spots/
-
Add images (optional):
- Place images in
frontend/public/matcha_spots/ - Set
imageUrlfield in Firestore to/matcha_spots/your-image.jpg
- Place images in
- Map View: Interactive map showing all matcha spots
- Sidebar: Searchable list of all spots with filters
- Featured Spots: Toggle to show only featured locations
- User Location: Click the location button to center map on your position
- Click the "Feed" button on the map
- Log in or register (if not already logged in)
- Fill out the experience form:
- Title (required)
- Content (required)
- Optional: Select a matcha spot
- Optional: Add a rating (1-5)
- Click "Post experience"
- Register: Click "Log in / Register" → Create account
- Log in: Enter your email and password
- Log out: Click your username in the Feed panel → Log out
cd frontend
npm startThe app will be available at http://localhost:3000
cd frontend
npm run buildThe build/ folder contains the production-ready app. Deploy this folder to Vercel, Netlify, or any static hosting service.
-
Install Vercel CLI (optional):
npm i -g vercel
-
Deploy:
cd frontend vercel -
Add environment variables in Vercel dashboard:
- Go to Project Settings → Environment Variables
- Add all
REACT_APP_FIREBASE_*variables from your.envfile
-
Redeploy after adding env vars
Make sure to add your Firebase config as environment variables in your hosting platform:
REACT_APP_FIREBASE_API_KEYREACT_APP_FIREBASE_AUTH_DOMAINREACT_APP_FIREBASE_PROJECT_IDREACT_APP_FIREBASE_APP_IDREACT_APP_FIREBASE_MESSAGING_SENDER_IDREACT_APP_FIREBASE_STORAGE_BUCKET
This means your Firestore security rules aren't set up correctly. See FIRESTORE_SETUP.md for detailed instructions.
- Make sure images are in
frontend/public/matcha_spots/ - Check that
imageUrlin Firestore starts with/matcha_spots/ - Verify image filenames match exactly (case-sensitive)
- Verify Firebase Authentication is enabled (Email/Password)
- Check that your
.envfile has correct Firebase config - Restart the dev server after changing
.envfile
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
See LICENSE file for details.
Built for UCI students to discover the best matcha spots in Irvine! 🍵