# Project export: IdealMeal

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: CruzHacks 2025
- Tagline: IdealMeal instantly connects you to food options—meals, recipes, or food items—utilizing AI to guide you to the best match for your dietary goals.
- Devpost: https://devpost.com/software/idealmeal
- GitHub: https://github.com/vineeshah/cruzhacks2025.git
- Demo: https://docs.google.com/presentation/d/1HF-udznHqZkzxRiQfkqzeQ52cqKeiWgPY_yGk7QevLU/edit?usp=sharing
- Team: 4 GitHub contributor(s) — aubreyshere (23 commits), vineeshah (17 commits), James Conrad Manlangit (12 commits), Hugh (3 commits)

## Devpost submission (written by the team)

### Inspiration

We all love food. But trying to eat healthy? That’s where things get complicated. Ever tried searching for a “healthy burger” and ended up with a quinoa patty sadness? Yeah, same. We built IdealMeal to fix that — to make eating better as simple (and satisfying) as your favorite takeout order. No guilt trips, no flavor sacrifices. Just straight to the good stuff.

### What it does

IdealMeal is your personal food GPS for healthier choices. Craving a burger? We’ll guide you to the best grass-fed, organic masterpiece nearby. Want to cook something at home? Here's a recipe that swaps the junk for fresh, tasty ingredients — without tasting like cardboard. Whether it's a restaurant, a recipe, or a grocery run, IdealMeal connects your cravings to your health goals — instantly.

### How we built it

We started with a big idea and broke it down bite by bite. The frontend’s built in React for a slick, responsive feel. On the backend, Python + Flask do the heavy lifting. We integrated Google’s Gemini AI to actually understand your cravings (because “salad” doesn’t always mean the same thing). Google Places API finds local options, and MongoDB tracks what you like, so it only gets smarter over time. It’s a tasty tech stack — just like our meals.

### Challenges we ran into

Where do we begin? Training AI to understand food cravings is like teaching a robot what "comfort food" feels like — not easy. Some early results included recommending kale chips for pizza cravings (rude). Then there was the rabbit hole of broken recipe links, closed restaurants, and overcomplicated interfaces. Our mantra became “make it smart, but make it simple.” Easier said than done — but we got there. Accomplishments we're proud of It works. Like, actually works. You tell IdealMeal what you’re in the mood for, and it shows you a healthier way to get there — whether it’s a nearby restaurant or a recipe you’ll actually want to cook. The interface is clean and user-friendly, and we’ve got a solid, growing base of verified recipes and places. Best part? It makes eating better feel less like a chore and more like a win.

### What we learned

People want to eat better — they just don’t want to spend 30 minutes hunting for that one decent recipe or driving across town for a sad salad. We learned that AI is powerful, but needs some human flavor to be truly helpful. We also discovered how big the demand is for something that makes healthy eating simple, accessible, and, most importantly, delicious. Bonus: we now know way more about food nutrition than we ever expected (ask us anything about fiber... please don’t).

### What's next

We’re just getting warmed up. We’re expanding our restaurant and recipe database daily. Up next? A feature to share your favorite finds with friends, social discovery, and personalized meal planning that actually makes sense. A mobile app is on the horizon (because healthy decisions should be pocket-sized). Long-term, we want to go global — healthy food should be easy to find, no matter where you are. Healthy eating shouldn't feel like a punishment — and with IdealMeal, it finally doesn't.

## README (from the GitHub repository)

# IdealMeal

Your personal guide to healthier eating, connecting you directly to healthier alternatives for any food craving.

## Features

-  Find healthier restaurant options near you
-  Access healthy recipes from trusted sources
-  Personalized recommendations based on your preferences
-  Filter by health goals and dietary restrictions
-  Clean, intuitive interface

## Prerequisites

- Python 3.8 or higher
- Node.js 14 or higher
- MongoDB
- Google Places API key
- Google Gemini API key

## Installation

### Backend Setup

1. Clone the repository:
```bash
git clone https://github.com/yourusername/idealmeal.git
cd idealmeal/backend
```

2. Create and activate a virtual environment:
```bash
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
```

3. Install Python dependencies:
```bash
pip install -r requirements.txt
```

4. Set up environment variables:
Create a `.env` file in the backend directory with:
```env
MONGODB_URI=your_mongodb_uri
GOOGLE_PLACES_API_KEY=your_google_places_api_key
GOOGLE_GEMINI_API_KEY=your_gemini_api_key
JWT_SECRET=your_jwt_secret
```

### Frontend Setup

1. Navigate to the frontend directory:
```bash
cd ../frontend
```

2. Install Node.js dependencies:
```bash
npm install
```

3. Create a `.env` file in the frontend directory:
```env
REACT_APP_API_URL=http://localhost:5000
```

## Running the Application

### Start the Backend Server

1. Make sure you're in the backend directory and your virtual environment is activated
2. Run the Flask server:
```bash
python app.py
```

The backend server will start on `http://localhost:5000`

### Start the Frontend Development Server

1. Make sure you're in the frontend directory
2. Start the React development server:
```bash
npm start
```

The frontend will start on `http://localhost:3000`

## API Documentation

The backend API documentation is available at `http://localhost:5000/api/docs` when the server is running.

## Contributing

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

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- Google Places API for location services
- Google Gemini AI for intelligent recommendations
- All the amazing recipe websites that make healthy eating possible

## Support

For support, email support@idealmeal.com or open an issue in the GitHub repository.


## Detected evidence (automated analysis)

Indexed codebase: 53 recognized source files, 150 KB.
- CSS (language) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- AWS (technology) — claimed on Devpost, not found in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- MongoDB (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (60 of 60)

```
.gitignore
backend/db.py
backend/models/__init__.py
backend/models/food.py
backend/models/recipe.py
backend/models/restaurant.py
backend/models/user.py
backend/routes/__init__.py
backend/routes/auth.py
backend/routes/food.py
backend/routes/recipes.py
backend/routes/restaurants.py
backend/routes/user.py
backend/run.py
backend/services/__init__.py
backend/services/food_service.py
backend/services/google_places_service.py
backend/services/recipe_search.py
backend/services/recs.py
backend/services/restaurant_service.py
backend/test_connections.py
frontend/.gitignore
frontend/package.json
frontend/public/index.html
frontend/public/manifest.json
frontend/public/robots.txt
frontend/README.md
frontend/src/App.css
frontend/src/App.js
frontend/src/Components/logo.css
frontend/src/Components/logo.js
frontend/src/Components/Navbar.css
frontend/src/Components/Navbar.js
frontend/src/Components/option-card.css
frontend/src/Components/option-card.js
frontend/src/Components/Recipe.css
frontend/src/Components/Recipe.js
frontend/src/Components/Wave.css
frontend/src/Components/Wave.js
frontend/src/Containers/Homepage.css
frontend/src/Containers/Homepage.js
frontend/src/Containers/Login.css
frontend/src/Containers/Login.js
frontend/src/Containers/Register.css
frontend/src/Containers/Register.js
frontend/src/Containers/RestaurantDetails.css
frontend/src/Containers/RestaurantDetails.js
frontend/src/Containers/TakeoutPage.css
frontend/src/Containers/TakeoutPage.js
frontend/src/Containers/UserSelectPage.css
frontend/src/Containers/UserSelectPage.js
frontend/src/Containers/WelcomePage.css
frontend/src/Containers/WelcomePage.js
frontend/src/contexts/AuthContext.js
frontend/src/index.css
frontend/src/index.js
frontend/src/services/api.js
package.json
README.md
requirements.txt
```

### Dependencies

- frontend/package.json: @testing-library/dom@^10.4.0, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.3.0, @testing-library/user-event@^13.5.0, react@^19.1.0, react-dom@^19.1.0, react-router-dom@^7.5.0, react-scripts@5.0.1, web-vitals@^2.1.4
- package.json: gsap@^3.12.7
- requirements.txt: annotated-types@==0.7.0, bcrypt@==4.3.0, blinker@==1.9.0, cachetools@==5.5.2, certifi@==2025.1.31, charset-normalizer@==3.4.1, click@==8.1.8, dnspython@==2.7.0, Flask@==3.1.0, Flask-Bcrypt@==1.0.1, flask-cors@==5.0.1, Flask-JWT-Extended@==4.7.1, Flask-PyMongo@==3.0.1, google-ai-generativelanguage@==0.6.15, google-api-core@==2.24.2, google-api-python-client@==2.166.0, google-auth@==2.38.0, google-auth-httplib2@==0.2.0, google-generativeai@==0.8.4, googleapis-common-protos@==1.69.2, googlemaps@==4.10.0, grpcio@==1.72.0rc1, grpcio-status@==1.71.0, httplib2@==0.22.0, httpx@==0.27.2, idna@==3.10, itsdangerous@==2.2.0, Jinja2@==3.1.6, MarkupSafe@==3.0.2, oauthlib@==3.2.2, proto-plus@==1.26.1, protobuf@==5.29.4, pyasn1@==0.6.1, pyasn1_modules@==0.4.2, pydantic@==2.11.3, pydantic_core@==2.33.1, PyJWT@==2.10.1, pymongo@==4.12.0, pyparsing@==3.2.3, python-dotenv@==1.1.0, requests@==2.32.3, rsa@==4.9, tqdm@==4.67.1, typing_extensions@==4.13.2, typing-inspection@==0.4.0, uritemplate@==4.1.1, urllib3@==2.4.0, Werkzeug@==3.1.3

### Recent commits (newest first)

- deleted config.py
- Merge branch 'main' of https://github.com/vineeshah/cruzhacks2025
- CSS on all pages
- Update README.md
- final css touches
- Merge pull request #3 from vineeshah/jio-branch
- fixing the recipe search linksss
- brought back the worm
- more fixes
- jio
- fixes
- Merge branch 'main' into jio-branch
- fix parsing pt 2
- Merge pull request #2 from vineeshah/css-work-now
- fix gemini response line parsing
- Update README.md
- test new gemini application for recipe page
- there were probelms
- ahh
- Merge pull request #1 from vineeshah/making_recipes

## Key source files (fetched from GitHub, selected and truncated for size)

### package.json

```
{
  "dependencies": {
    "gsap": "^3.12.7"
  }
}

```

### requirements.txt

```
annotated-types==0.7.0
bcrypt==4.3.0
blinker==1.9.0
cachetools==5.5.2
certifi==2025.1.31
charset-normalizer==3.4.1
click==8.1.8
dnspython==2.7.0
Flask==3.1.0
Flask-Bcrypt==1.0.1
flask-cors==5.0.1
Flask-JWT-Extended==4.7.1
Flask-PyMongo==3.0.1
google-ai-generativelanguage==0.6.15
google-api-core==2.24.2
google-api-python-client==2.166.0
google-auth==2.38.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.4
googleapis-common-protos==1.69.2
googlemaps==4.10.0
grpcio==1.72.0rc1
grpcio-status==1.71.0
httplib2==0.22.0
httpx==0.27.2
idna==3.10
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.2
oauthlib==3.2.2
proto-plus==1.26.1
protobuf==5.29.4
pyasn1==0.6.1
pyasn1_modules==0.4.2
pydantic==2.11.3
pydantic_core==2.33.1
PyJWT==2.10.1
pymongo==4.12.0
pyparsing==3.2.3
python-dotenv==1.1.0
requests==2.32.3
rsa==4.9
tqdm==4.67.1
typing-inspection==0.4.0
typing_extensions==4.13.2
uritemplate==4.1.1
urllib3==2.4.0
Werkzeug==3.1.3
```

### frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.3.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^19.1.0",
    "react-dom": "^19.1.0",
    "react-router-dom": "^7.5.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

### frontend/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client'; // Import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'; // Import BrowserRouter
import './index.css';
import App from './App';

// Create the root element
const root = ReactDOM.createRoot(document.getElementById('root'));

// Render the application
root.render(
    <React.StrictMode>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </React.StrictMode>
);
```

### frontend/src/App.js

```javascript
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Homepage from './Containers/Homepage';
import Login from './Containers/Login';
import Register from './Containers/Register';
import WelcomePage from './Containers/WelcomePage';
import UserSelect from './Containers/UserSelectPage';
import Takeout from './Containers/TakeoutPage';
import RestaurantDetails from './Containers/RestaurantDetails';
import Recipe from './Components/Recipe';
// import PrivateRoute from './Components/PrivateRoute';
import './App.css';

function App() {
    return (
        <div className="App">
            <div className="content">
                <Routes>
                    <Route path="/" element={<Homepage />} />
                    <Route path="/login" element={<Login />} />
                    <Route path="/register" element={<Register />} />
                    <Route path="/welcome" element={<WelcomePage />} />
                    <Route path="/user-select" element={<UserSelect />} />
                    <Route path="/takeout" element={<Takeout />} />
                    <Route path="/restaurants/:placeId" element={<RestaurantDetails />} />
                    <Route path="/recipes" element={<Recipe />} />
                </Routes>
            </div>
        </div>
    );
}

export default App;

```

### backend/db.py

```python
from flask_pymongo import PyMongo
from config import Config

mongo = PyMongo() 
```

### backend/run.py

```python
from flask import Flask, jsonify
from flask_cors import CORS
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager
import os
from datetime import timedelta
from config import Config
from db import mongo

def create_app():
    # Create Flask app
    app = Flask(__name__)

    # Configure app
    app.config["MONGO_URI"] = Config.MONGO_URI
    app.config["GEMINI_API_KEY"] = Config.GEMINI_API_KEY
    app.config["JWT_SECRET_KEY"] = Config.JWT_SECRET_KEY
    app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1)

    # Initialize extensions
    mongo.init_app(app)
    bcrypt = Bcrypt(app)
    jwt = JWTManager(app)
    CORS(app)

    # Import and register blueprints
    from routes.auth import auth_bp
    from routes.food import food_bp
    from routes.recipes import recipe_bp
    from routes.restaurants import restaurants_bp
    from routes.user import user_bp

    app.register_blueprint(auth_bp, url_prefix='/api/auth')
    app.register_blueprint(food_bp, url_prefix='/api/food')
    app.register_blueprint(recipe_bp, url_prefix='/api/recipes')
    app.register_blueprint(restaurants_bp, url_prefix='/api/restaurants')
    app.register_blueprint(user_bp, url_prefix='/api/user')

    return app

if __name__ == '__main__':
    app = create_app()
    app.run(debug=True, port=5000)
```

### backend/test_connections.py

```python
from pymongo import MongoClient
from config import Config
import google.generativeai as genai
import googlemaps
import sys
import ssl
import certifi

# def list_gemini_models():
#     try:
#         print("\nListing available Gemini models...")
#         genai.configure(api_key=Config.GEMINI_API_KEY)
#         for m in genai.list_models():
#             if 'generateContent' in m.supported_generation_methods:
#                 print(f"Model: {m.name}")
#                 print(f"Description: {m.description}")
#                 print(f"Supported methods: {m.supported_generation_methods}")
#                 print("---")
#         return True
#     except Exception as e:
#         print(f"❌ Failed to list models: {str(e)}")
#         return False

def test_mongodb_connection():
    try:
        print("Attempting to connect to MongoDB...")
        print(f"Python version: {sys.version}")
        print(f"SSL version: {ssl.OPENSSL_VERSION}")
        print(f"Using connection string: {Config.MONGO_URI}")
        
        # Test connection with SSL verification
        client = MongoClient(
            Config.MONGO_URI,
            serverSelectionTimeoutMS=30000,
            socketTimeoutMS=30000,
            connectTimeoutMS=30000,
            retryWrites=True,
            retryReads=True,
            maxPoolSize=50,
            minPoolSize=10,
            tlsCAFile=certifi.where(),
            tlsAllowInvalidCertificates=False,
            tlsAllowInvalidHostnames=False
        )
        
        # Force a connection and get server info
        print("\nTesting server connection...")
        server_info = client.server_info()
        print("✅ Server connection successful!")
        print(f"Server version: {server_info.get('version', 'unknown')}")
        print(f"Server type: {server_info.get('type', 'unknown')}")
        
        # Test database access
        print("\nTesting database access...")
        db = client.get_database()
        print(f"✅ Connected to database: {db.name}")
        
        # List all collections
        print("\nCollections in database:")
        for collection in db.list_collection_names():
            print(f"- {collection}")
        
        return True
    except Exception as e:
        print(f"\n❌ MongoDB connection failed: {str(e)}")
        print(f"Connection URI: {Config.MONGO_URI}")
        print(f"Error type: {type(e).__name__}")
        print("\nTroubleshooting steps:")
        print("1. Check if your IP address is whitelisted in MongoDB Atlas")
        print("2. Verify your MongoDB Atlas cluster is running")
        print("3. Check your internet connection")
        print("4. Try connecting using MongoDB Compass")
        print("5. Verify the connection string matches exactly with Compass")
        print("6. Check if SSL certificates are properly installed")
        return False

def test_gemini_connection():
    try:
        print("\nAttempting to connect to Gemini API...")
        genai.configure(api_key=Config.GEMINI_API_KEY)
        model = genai.GenerativeModel('gemini-1.5-pro')
        response = model.generate_content("Hello")
        print("✅ Gemini API connection successful!")
        return True
    except Exception as e:
        print(f"❌ Gemini API connection failed: {str(e)}")
        return False

def test_google_places_connection():
    try:
        print("\nAttempting to connect to Google Places API...")
        print(f"Using API Key: {Config.GOOGLE_PLACES_API_KEY[:10]}...")
        
        # Test direct client creation
        client = googlemaps.Client(key=Config.GOOGLE_PLACES_API_KEY)
        print("✅ Google Maps client created successfully")
        
        # Test with a known place ID (e.g., Google HQ)
        result = client.place('ChIJj61dQgK6j4AR4GeTYWZsKWw', fields=['name', 'formatted_address'])
        print("✅ Google Places API connection successful")
        print(f"Test place: {result.get('result', {}).get('name', 'Unknown')}")
        print(f"Address: {result.get('result', {}).get('formatted_address', 'Unknown')}")
        return True
    except Exception as e:
        print(f"❌ Google Places API connection failed: {e}")
        print("Error details:")
        print(f"Status: {getattr(e, 'status_code', 'Unknown')}")
        print(f"Message: {str(e)}")
        return False

if __name__ == "__main__":
    print("Testing all API connections...")
    print("Python version:", sys.version)
    
    # List Gemini models first
    # list_gemini_models()
    
    mongo_success = test_mongodb_connection()
    gemini_success = test_gemini_connection()
    places_success = test_google_places_connection()
    
    if all([mongo_success, gemini_success, places_success]):
        print("\n🎉 All connections successful!")
    else:
        print("\n❌ Some connections failed. Please check the error messages above.") 
```

### backend/services/__init__.py

```python
# Services package initialization
from .recs import RecommendationService
from .google_places_service import GooglePlacesService

__all__ = ['RecommendationService', 'GooglePlacesService']

```

### backend/models/__init__.py

```python
# Import models
from .user import User
from .food import Food
from .recipe import Recipe
from .restaurant import Restaurant

# Export models
__all__ = ['User', 'Food', 'Recipe', 'Restaurant']
```

[44 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]