Skip to content
imRanDanPublic

About

CafeQuest is a web application designed to help users discover, review, and rate local cafes. With an emphasis on providing a seamless user experience, the app allows users to find their favorite spots, leave reviews, and explore cafes through an interactive map. Whether you're a coffee aficionado or just looking for a cozy spot to work.

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

☕ CafeQuest

Discover local cafes and save your favorites

Live Demo Next.js React Firebase

Live Demo · Report Bug · Request Feature


📖 About The Project

CafeQuest is a location-based cafe discovery web application that helps coffee lovers find nearby cafes using real-time data from OpenStreetMap. Built with Next.js 15 and Firebase, it features an interactive Mapbox map, smart filtering options, and the ability to save favorite cafes to a personal dashboard.

✨ Key Highlights

  • 🗺️ Interactive Mapbox Map with custom cafe markers and real-time user location
  • 🔍 Google Places Autocomplete for intelligent location search
  • 🎯 Smart Filtering - Hide chains (Tim Hortons, Starbucks) and find late-night cafes (open ≥ 9pm)
  • 💾 Personal Dashboard with Firebase Firestore to save and manage favorite cafes
  • 🔐 Secure Authentication with Firebase Auth and protected routes
  • 📱 Responsive Design with mobile-optimized navigation
  • ⚡ Performance Optimized with API request caching and rate limiting

🖼️ Screenshots

Homepage & Map Interface

Homepage

User Authentication

Login

Interactive Map with Filters

Map Interface


🚀 Features

Core Functionality

  • 📍 Location Search – Google Places autocomplete with fallback to Nominatim API
  • 🗺️ Mapbox Integration – Interactive map powered by Mapbox GL JS and react-map-gl
  • 📌 GPS Location – Automatic user location detection with geolocation API
  • ☕ Real-time Cafe Data – Fetches cafes from OpenStreetMap via Overpass API (5km radius)
  • 🔍 Smart Filters:
    • Hide Tim Hortons
    • Hide Starbucks
    • Show only late-night cafes (open ≥ 9pm)
  • 💾 Save Cafes – Bookmark cafes with name, address, and opening hours
  • 🗑️ Manage Favorites – Delete cafes from your saved list
  • 📊 Cafe Details – View address, opening hours, and link to Google Maps

Technical Features

  • 🔒 Protected Routes – Dashboard and profile require authentication
  • 🎨 Chakra UI – Modern component library with dark mode support
  • ⚡ API Optimization:
    • Request caching (30-minute expiration)
    • Rate limiting (1 request/second)
    • Debounced search input (400ms)
  • 🔔 Toast Notifications – User feedback for all actions
  • 📱 Responsive UI – Mobile menu with Avatar dropdown
  • 🎭 Loading States – Spinners for async operations
  • 🔥 Firebase Integration:
    • Email/password authentication
    • Firestore for user data and saved cafes
    • Security rules for data protection
  • 📈 Vercel Analytics – Built-in analytics tracking

🛠️ Tech Stack

Frontend

Backend / Services

Libraries & Tools

Development Tools


📦 Getting Started

Prerequisites

  • Node.js 18+ (Download)
  • Firebase Project with Firestore and Authentication enabled (Setup Guide)
  • Google Maps API Key with Places API enabled (Get API Key)
  • Mapbox Access Token (Sign up)

Installation

  1. Clone the repository
git clone https://github.com/imRanDan/cafequest.git
cd cafequest
  1. Install dependencies
npm install
  1. Configure environment variables

Create a .env.local file in the root directory:

# Firebase Configuration
NEXT_PUBLIC_FIREBASE_API_KEY=your_firebase_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id

# Google Maps API Key
NEXT_PUBLIC_GOOGLE_API_KEY=your_google_maps_api_key

# Mapbox Access Token
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=your_mapbox_token
  1. Set up Firebase Firestore Security Rules

In your Firebase Console, navigate to Firestore Database > Rules and add:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // User documents
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
      
      // Saved cafes subcollection
      match /savedCafes/{cafeId} {
        allow read, write: if request.auth != null && request.auth.uid == userId;
      }
      
      // Visited cafes subcollection (passport)
      match /visitedCafes/{cafeId} {
        allow read, write: if request.auth != null && request.auth.uid == userId;
      }
    }
    
    // Cafe votes collection - community voting system
    match /cafeVotes/{cafeId} {
      // Allow anyone to read votes (for displaying aggregated results)
      allow read: if true;
      
      // Votes subcollection
      match /votes/{userId} {
        // Users can read all votes (for aggregation)
        allow read: if true;
        
        // Users can only write their own vote
        allow create, update: if request.auth != null && request.auth.uid == userId;
        
        // Users can delete their own vote
        allow delete: if request.auth != null && request.auth.uid == userId;
      }
    }
  }
}
  1. Enable Authentication in Firebase

    • Go to Firebase Console > Authentication
    • Enable "Email/Password" sign-in method
  2. Run the development server

npm run dev

Open http://localhost:3000 in your browser.


🧪 Testing

Run the test suite:

npm test

Current test coverage includes:

  • Map.test.jsx – Map component rendering and interactions
  • SearchBar.test.jsx – Search functionality

🏗️ Project Structure

cafequest/
├── src/
│   ├── app/                          # Next.js App Router pages
│   │   ├── dashboard/                # User dashboard (protected)
│   │   │   └── page.jsx              # Displays saved cafes as cards
│   │   ├── profile/                  # User profile (protected)
│   │   │   └── page.jsx              # User info and logout
│   │   ├── login/                    # Login page
│   │   │   └── page.jsx              # Email/password login
│   │   ├── signup/                   # Sign up page
│   │   │   └── page.jsx              # User registration with Firestore
│   │   ├── layout.js                 # Root layout with Navbar, Footer, Providers
│   │   ├── page.js                   # Homepage with map and filters
│   │   └── globals.css               # Global styles
│   ├── components/                   # React components
│   │   ├── Map.jsx                   # Mapbox map with markers & popups
│   │   ├── CafeCard.jsx              # Cafe card for dashboard
│   │   ├── LocationSearchInput.jsx   # Google Places autocomplete
│   │   ├── Navbar.jsx                # Navigation with auth state
│   │   ├── Footer.jsx                # Footer component
│   │   ├── LoadingSpinner.jsx        # Loading indicator
│   │   └── ...                       # Other UI components
│   ├── config/                       # Configuration files
│   │   └── firebase.js               # Firebase initialization
│   ├── utils/                        # Utility functions
│   │   ├── AuthProvider.js           # Auth context provider
│   │   └── ThemeProvider.js          # Theme context provider
│   ├── providers/                    # Context providers
│   │   └── Providers.jsx             # Combines all providers
│   └── styles/                       # Additional styles
├── images/                           # Screenshots
├── jest.config.js                    # Jest configuration
├── jest.setup.js                     # Jest setup file
├── package.json                      # Dependencies
└── README.md

🎯 How It Works

Location Search Flow

  1. User types in the search box (powered by Google Places autocomplete)
  2. User selects a location or clicks "Search"
  3. Location is geocoded to latitude/longitude
  4. Overpass API fetches cafes within 5km radius
  5. Results are cached for 30 minutes
  6. Markers appear on the Mapbox map

Filtering System

  • Hide Tim Hortons/Starbucks: Filters by cafe name
  • Open Late: Parses opening_hours tag from OSM data, excludes cafes closing before 9pm

Save Cafe Flow

  1. User clicks marker on map → popup appears
  2. User clicks "Save" button
  3. Checks if user is logged in (Firebase Auth)
  4. Saves to Firestore: users/{userId}/savedCafes/{cafeId}
  5. Toast notification confirms save
  6. Cafe appears on dashboard

📝 Usage

For Users

  1. Browse Cafes

    • Visit homepage
    • Allow location access or search for a city/postal code
    • Click "Show cafes near me" or use the search bar
  2. Filter Results

    • Toggle switches to hide Tim Hortons or Starbucks
    • Enable "Open late" to find cafes open past 9pm
  3. Create Account

    • Click "Sign Up"
    • Enter full name, email, and password
    • Account is created in Firebase
  4. Save Cafes

    • Click any cafe marker on the map
    • View details in the popup
    • Click "Save" (requires login)
    • Access saved cafes from Dashboard
  5. Manage Favorites

    • Navigate to Dashboard
    • View all saved cafes as cards
    • Click "Delete" to remove

🚧 Roadmap

  • Mapbox integration with custom markers
  • Google Places autocomplete search
  • GPS location detection
  • Smart filters (chains, late-night)
  • User authentication with Firebase
  • Save cafes to Firestore
  • User dashboard with cafe cards
  • Delete saved cafes
  • Responsive mobile design
  • API caching and rate limiting
  • Search/filter within saved cafes
  • Cafe photos from Google Places API
  • User reviews and ratings
  • Share cafes with friends
  • PWA support for offline access
  • Email verification
  • Password reset functionality

🤝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📝 License

Distributed under the MIT License. See LICENSE for more information.


👤 Author

Danyal Imran


🙏 Acknowledgments


🔧 API Rate Limits & Best Practices

This project implements several optimizations:

  • Caching: API responses cached for 30 minutes
  • Rate Limiting: Max 1 request per second to Overpass API
  • Debouncing: Search input debounced to 400ms
  • Request Limiting: Display limit of 10 markers initially, loads more on map movement

Made with ☕ by Danyal Imran

⭐ Star this repo if you found it helpful!

About

CafeQuest is a web application designed to help users discover, review, and rate local cafes. With an emphasis on providing a seamless user experience, the app allows users to find their favorite spots, leave reviews, and explore cafes through an interactive map. Whether you're a coffee aficionado or just looking for a cozy spot to work.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages