Skip to content

imRanDan/cafequest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

166 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors