Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Documentation and project management folders
docs/
.github/

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# IDE/Editor files
.vscode/
.idea/
*.swp
*.swo
*~

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
84 changes: 83 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,83 @@
# js-project-recipe-library
# Recipe Library

A progressive recipe discovery app built over Weeks 5-7 of the Web Development Bootcamp. Features Spoonacular API integration, intelligent caching, search functionality, favorites system, and pagination.

## Live Demo & Screenshot

- **Live App:** https://recipelibrarya.netlify.app
- **Screenshot:**

![Recipe Library Screenshot](/screenshot/screenshot.png)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to add a screen shot of the finished result in readme file


## Features

### Core Functionality
- **Responsive Design** - Mobile-first layout (320px to 1600px+)
- **Dynamic Recipe Display** - Template literal-based card generation
- **Multi-Filter System** - Diet, cuisine, and sorting filters work together
- **Search** - Real-time search by title and ingredients with 300ms debouncing
- **Random Recipe** - Discover new recipes with dice button
- **Empty States** - Helpful guidance when no results found

### Advanced Features
- **Spoonacular API Integration** - Fetches up to 100 fresh recipes
- **Smart Caching** - 24-hour localStorage cache with backup fallback
- **Favorites System** - Save/unsave recipes with localStorage persistence
- **Pagination** - 15 recipes per page with navigation controls
- **Loading States** - Clear feedback during async operations
- **Progressive Enhancement** - Works offline with backup data (19 recipes)

## Technical Implementation

### Data Flow
```
Spoonacular API → localStorage Cache → Backup Data
Data Normalization (mapSpoonacularToLocal)
Filter Chain: Search → Filter → Sort → Display
```

### Key Technologies
- **Vanilla JavaScript** - ES6+ with async/await, template literals, array methods
- **CSS Grid + Flexbox** - Modern responsive layout
- **CSS Custom Properties** - Centralized theming system
- **Fetch API** - External data integration with error handling

### Performance Optimizations
- Debounced search input (300ms)
- Pagination for large datasets
- Lazy image loading
- Intelligent caching strategy
- Loading messages with 2-second minimum display time to showcase

## Getting Started
1. Clone the repository and open `index.html` in your browser.
2. The app functions fully with live API data, cached recipes, and backup recipes for offline or quota-exceeded scenarios.

## File Structure

```
├── index.html # Main application
├── script.js # Core logic (~800 lines)
├── styles.css # Responsive styling (~531 lines)
└── backupdata.js # Fallback recipes (19 items)
```

## Requirements Met

**Week 5-7 Core Requirements**: ✅ All completed
- Responsive HTML/CSS structure
- Filter and sorting functionality
- Array manipulation and recipe display
- API integration with error handling
- localStorage caching

**Stretch Goals Achieved**: ✅ 6/6 completed
- Multiple filters working together
- Search functionality for specific recipe names or ingredients with debouncing
- Favorites system with persistence
- Pagination for performance
- Loading states and error handling
- Local storage caching

254 changes: 254 additions & 0 deletions backupdata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
// Minimal backup recipe data - 19 recipes only
// Recipe IDs: 658753, 644846, 635345, 982376, 634204, 665403, 661218, 634171, 1062883, 647615, 654504, 649030, 664284, 641145, 644642, 645732, 1043340, 645068, 634854

const backupData = {
"recipes": [
{
"id": 658753,
"title": "Roma Tomato Bruschetta",
"image": "https://img.spoonacular.com/recipes/658753-556x370.jpg",
"readyInMinutes": 45,
"servings": 4,
"sourceUrl": "https://www.foodista.com/recipe/M3RH6LBH/roma-tomato-bruschetta",
"diets": ["vegetarian", "vegan"],
"cuisine": ["mediterranean", "italian"],
"ingredients": ["balsamic vinegar", "bread", "basil", "garlic", "tomatoes"],
"pricePerServing": 1.89,
"popularity": 5
},
{
"id": 644846,
"title": "Gluten Free Onion Rings",
"image": "https://img.spoonacular.com/recipes/644846-556x370.jpg",
"readyInMinutes": 45,
"servings": 4,
"sourceUrl": "https://www.foodista.com/recipe/L5CSWWPM/gluten-free-onion-rings",
"diets": ["vegetarian"],
"cuisine": ["american"],
"ingredients": ["egg", "oil", "milk", "onions"],
"pricePerServing": 0.86,
"popularity": 38
},
{
"id": 635345,
"title": "Blue Cheese and Mushroom Turkey Burger",
"image": "https://img.spoonacular.com/recipes/635345-556x370.jpg",
"readyInMinutes": 45,
"servings": 1,
"sourceUrl": "https://www.foodista.com/recipe/3JGSVVX8/blue-cheese-and-mushroom-turkey-burger",
"diets": [],
"cuisine": ["american"],
"ingredients": ["garlic cloves", "ground turkey", "mushrooms", "soy sauce"],
"pricePerServing": 2.32,
"popularity": 2
},
{
"id": 982376,
"title": "Chicken Noodle Casserole Dish",
"image": "https://img.spoonacular.com/recipes/982376-556x370.jpg",
"readyInMinutes": 55,
"servings": 6,
"sourceUrl": "https://www.pinkwhen.com/chicken-noodle-casserole-dish/",
"diets": [],
"cuisine": ["american"],
"ingredients": ["bread crumbs", "carrots", "chicken broth", "chicken", "mozzarella"],
"pricePerServing": 2.50,
"popularity": 5
},
{
"id": 634204,
"title": "Banana Walnut Cinnamon Bread",
"image": "https://img.spoonacular.com/recipes/634204-556x370.jpg",
"readyInMinutes": 45,
"servings": 8,
"sourceUrl": "http://www.foodista.com/recipe/CCDRBSRB/banana-walnut-cinnamon-bread",
"diets": ["vegetarian"],
"cuisine": [],
"ingredients": ["baking powder", "eggs", "flour", "salt", "vanilla extract"],
"pricePerServing": 0.41,
"popularity": 3
},
{
"id": 665403,
"title": "Wisconsin Beer Cheese Soup",
"image": "https://img.spoonacular.com/recipes/665403-556x370.jpg",
"readyInMinutes": 45,
"servings": 4,
"sourceUrl": "https://www.foodista.com/recipe/VPR24J2V/wisconsin-beer-cheese-soup",
"diets": [],
"cuisine": ["american"],
"ingredients": ["butter", "flour", "beer", "mustard", "salt"],
"pricePerServing": 1.60,
"popularity": 2
},
{
"id": 661218,
"title": "Spicy Tuna Cakes",
"image": "https://img.spoonacular.com/recipes/661218-556x370.jpg",
"readyInMinutes": 45,
"servings": 3,
"sourceUrl": "https://www.foodista.com/recipe/HWFXR7RN/spicy-tuna-cakes",
"diets": [],
"cuisine": [],
"ingredients": ["breadcrumbs", "tuna", "egg", "hot sauce"],
"pricePerServing": 1.84,
"popularity": 5
},
{
"id": 634171,
"title": "Banana Pudding Cake",
"image": "https://img.spoonacular.com/recipes/634171-556x370.jpg",
"readyInMinutes": 45,
"servings": 12,
"sourceUrl": "https://www.foodista.com/recipe/NM38YSZL/banana-pudding-cake",
"diets": [],
"cuisine": [],
"ingredients": ["baking powder", "cocoa", "eggs", "sugar", "vanilla wafers"],
"pricePerServing": 2.36,
"popularity": 3
},
{
"id": 1062883,
"title": "How to Make Easy Cheesy Garlic Bread",
"image": "https://img.spoonacular.com/recipes/1062883-556x370.jpg",
"readyInMinutes": 15,
"servings": 8,
"sourceUrl": "https://www.pinkwhen.com/easy-cheesy-garlic-bread/",
"diets": [],
"cuisine": [],
"ingredients": ["bread", "butter", "cheese", "garlic", "olive oil"],
"pricePerServing": 0.75,
"popularity": 5
},
{
"id": 647615,
"title": "Huli-Huli Chicken",
"image": "https://img.spoonacular.com/recipes/647615-556x370.jpg",
"readyInMinutes": 45,
"servings": 6,
"sourceUrl": "https://www.foodista.com/recipe/BDBHNYGT/huli-huli-chicken",
"diets": [],
"cuisine": ["hawaiian"],
"ingredients": ["chicken drumsticks", "garlic", "ginger", "pineapple"],
"pricePerServing": 0.52,
"popularity": 2
},
{
"id": 654504,
"title": "Pancit Bihon (Filipino Pancit)",
"image": "https://img.spoonacular.com/recipes/654504-556x370.jpg",
"readyInMinutes": 45,
"servings": 6,
"sourceUrl": "https://www.foodista.com/recipe/LDWW4QDB/pancit-bihon-filipino-pancit",
"diets": [],
"cuisine": ["filipino", "asian"],
"ingredients": ["rice vermicelli", "cabbage", "carrots", "chicken", "shrimp"],
"pricePerServing": 3.10,
"popularity": 3
},
{
"id": 649030,
"title": "Korean Style Beef and Vegetables Over Rice",
"image": "https://img.spoonacular.com/recipes/649030-556x370.jpg",
"readyInMinutes": 45,
"servings": 4,
"sourceUrl": "https://www.foodista.com/recipe/5LTQJ3V2/korean-style-beef-and-vegetables-over-rice",
"diets": [],
"cuisine": ["korean", "asian"],
"ingredients": ["beef", "carrots", "green beans", "rice", "sesame oil"],
"pricePerServing": 3.46,
"popularity": 2
},
{
"id": 664284,
"title": "Vanilla and Lime Flan",
"image": "https://img.spoonacular.com/recipes/664284-556x370.jpg",
"readyInMinutes": 45,
"servings": 8,
"sourceUrl": "https://www.foodista.com/recipe/TMCNMVR/vanilla-and-lime-flan",
"diets": ["vegetarian"],
"cuisine": ["mexican"],
"ingredients": ["condensed milk", "eggs", "lime", "vanilla pod", "water"],
"pricePerServing": 1.43,
"popularity": 2
},
{
"id": 641145,
"title": "Curry-Braised Chicken",
"image": "https://img.spoonacular.com/recipes/641145-556x370.jpg",
"readyInMinutes": 75,
"servings": 4,
"sourceUrl": "http://www.foodista.com/recipe/YN6PSSKQ/curry-braised-chicken",
"diets": [],
"cuisine": ["indian", "asian"],
"ingredients": ["basmati rice", "chicken breast", "curry paste", "coconut milk"],
"pricePerServing": 2.20,
"popularity": 2
},
{
"id": 644642,
"title": "Ginger Snap and Pumpkin Ice Cream Sandwiches",
"image": "https://img.spoonacular.com/recipes/644642-556x370.jpg",
"readyInMinutes": 45,
"servings": 20,
"sourceUrl": "https://www.foodista.com/recipe/5ZY78MKS/ginger-snap-and-pumpkin-ice-cream-sandwiches",
"diets": ["vegetarian"],
"cuisine": [],
"ingredients": ["flour", "sugar", "ginger", "cinnamon", "pumpkin"],
"pricePerServing": 0.76,
"popularity": 2
},
{
"id": 645732,
"title": "Grilled Ham and Cheese French Toast",
"image": "https://img.spoonacular.com/recipes/645732-556x370.jpg",
"readyInMinutes": 20,
"servings": 4,
"sourceUrl": "https://www.foodista.com/recipe/NYVTQ65V/grilled-ham-and-cheese-french-toast",
"diets": [],
"cuisine": ["american"],
"ingredients": ["buttermilk", "egg whites", "mustard", "wheat bread", "ham"],
"pricePerServing": 1.34,
"popularity": 2
},
{
"id": 1043340,
"title": "The BEST Sweet Potato Casserole",
"image": "https://img.spoonacular.com/recipes/1043340-556x370.jpg",
"readyInMinutes": 40,
"servings": 6,
"sourceUrl": "https://www.pinkwhen.com/sweet-potato-casserole-gourmet-holiday-baking/",
"diets": ["vegetarian"],
"cuisine": ["american"],
"ingredients": ["sweet potatoes", "butter", "eggs", "vanilla extract", "cinnamon"],
"pricePerServing": 1.89,
"popularity": 5
},
{
"id": 645068,
"title": "Gooey Chocolate Buttermilk Sheet Cake",
"image": "https://img.spoonacular.com/recipes/645068-556x370.jpg",
"readyInMinutes": 45,
"servings": 12,
"sourceUrl": "https://www.foodista.com/recipe/GJ66TZ5G/gooey-chocolate-buttermilk-sheet-cake",
"diets": ["vegetarian"],
"cuisine": [],
"ingredients": ["flour", "baking soda", "butter", "eggs", "sugar"],
"pricePerServing": 0.39,
"popularity": 3
},
{
"id": 634854,
"title": "Berry Fruit Crumble",
"image": "https://img.spoonacular.com/recipes/634854-556x370.jpg",
"readyInMinutes": 45,
"servings": 6,
"sourceUrl": "https://www.foodista.com/recipe/67KX7C62/berry-fruit-crumble",
"diets": [],
"cuisine": [],
"ingredients": ["berries", "maple syrup", "oatmeal", "almond meal", "brown sugar"],
"pricePerServing": 1.51,
"popularity": 18
}
]
}
Loading