In today’s fast-paced world, managing food inventory efficiently is essential for minimizing waste and ensuring that meals are prepared with the freshest ingredients. With the rise of modern web technologies, it’s possible to create powerful, user-friendly applications that streamline this process. In this article, we will guide you through building a Food Inventory Management App using Next.js, Material-UI, Firebase, Flask, and Hugging Face to track food items and generate recipe suggestions.
Technology Stack Overview
- Next.js: A React framework that simplifies server-side rendering and static website generation.
- Material-UI (MUI): A popular component library for building responsive and visually appealing UIs in React applications.
- Firebase: A cloud-based platform that provides backend services, such as real-time databases and user authentication.
- Flask: A lightweight Python web framework used to build the backend API for interacting with Hugging Face.
- Hugging Face: A platform offering state-of-the-art NLP models, which we will use to generate recipes based on available ingredients.
Setting up the Next.js and Material-UI Frontend
Initializing the Next.js Project
To get started, create a new Next.js project:
npx create-next-app food-inventory-app
cd food-inventory-app
npm install @mui/material @emotion/react @emotion/styled
Next.js will provide the foundation for building the app’s user interface, while Material-UI (MUI) will help style the components and maintain a clean, responsive layout.
Creating Material-UI Components
Let’s create a simple form that allows users to input food items into the inventory:
// components/FoodItemForm.js
import { useState } from 'react';
import { TextField, Button } from '@mui/material';
export default function FoodItemForm({ addFoodItem }) {const [itemName, setItemName] = useState(”);
const handleSubmit = (e) => {e.preventDefault();
if (itemName) {
addFoodItem(itemName);
setItemName(”);
}
};
return (<form onSubmit={handleSubmit}>
<TextField
label=“Food Item”
value={itemName}
onChange={(e) => setItemName(e.target.value)}
variant=”outlined”
/>
<Button type=“submit” variant=“contained” color=“primary”>
Add Item
</Button>
</form>
);
}
Displaying the Food Inventory
To display the list of food items, we will create a component that maps over the array of items and renders them in a list:
// components/FoodInventory.js
import { List, ListItem, ListItemText } from '@mui/material';
export default function FoodInventory({ inventory }) {return (
<List>
{inventory.map((item, index) => (
<ListItem key={index}>
<ListItemText primary={item} />
</ListItem>
))}
</List>
);
}
Integrating Components in the Main Page
Next, we will integrate the form and the inventory list into the main page of the app:
// pages/index.js
import { useState } from 'react';
import FoodItemForm from '../components/FoodItemForm';
import FoodInventory from '../components/FoodInventory';
export default function Home() {const [inventory, setInventory] = useState([]);
const addFoodItem = (item) => {setInventory([…inventory, item]);
};
return (<div>
<h1>Food Inventory Management</h1>
<FoodItemForm addFoodItem={addFoodItem} />
<FoodInventory inventory={inventory} />
</div>
);
}
This will create a simple UI where users can add food items to an inventory and view the list dynamically.
Storing Inventory Data in Firebase
Setting Up Firebase
First, create a Firebase project and set up Firestore, Firebase’s NoSQL database, to store the inventory data.
Install Firebase SDK:
npm install firebase
Initialize Firebase in your project:
// lib/firebase.js
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {apiKey: “YOUR_API_KEY”,
authDomain: “YOUR_AUTH_DOMAIN”,
projectId: “YOUR_PROJECT_ID”,
storageBucket: “YOUR_STORAGE_BUCKET”,
messagingSenderId: “YOUR_MESSAGING_SENDER_ID”,
appId: “YOUR_APP_ID”
};
const app = initializeApp(firebaseConfig);const db = getFirestore(app);
export { db };Writing Data to Firestore
Modify the addFoodItem
function to store data in Firestore:
// pages/index.js
import { collection, addDoc } from 'firebase/firestore';
import { db } from '../lib/firebase';
export default function Home() {const [inventory, setInventory] = useState([]);
const addFoodItem = async (item) => {await addDoc(collection(db, ‘inventory’), { name: item });
setInventory([…inventory, item]);
};
return (<div>
<h1>Food Inventory Management</h1>
<FoodItemForm addFoodItem={addFoodItem} />
<FoodInventory inventory={inventory} />
</div>
);
}
Retrieving Data from Firestore
To retrieve the data from Firebase and display it in the app:
// pages/index.js
import { collection, getDocs } from 'firebase/firestore';
import { useEffect } from 'react';
export default function Home() {const [inventory, setInventory] = useState([]);
useEffect(() => {const fetchInventory = async () => {
const querySnapshot = await getDocs(collection(db, ‘inventory’));
setInventory(querySnapshot.docs.map((doc) => doc.data().name));
};
fetchInventory();}, []);
return (<div>
<h1>Food Inventory Management</h1>
<FoodItemForm addFoodItem={addFoodItem} />
<FoodInventory inventory={inventory} />
</div>
);
}
Backend with Flask and Hugging Face for Recipe Generation
Setting Up Flask
Install Flask and set up a simple API that communicates with Hugging Face’s models to generate recipes:
pip install Flask
Create the Flask app:
# app.py
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
def generate_recipe():
ingredients = request.json.get(‘ingredients’, [])
model_endpoint = ‘https://api-inference.huggingface.co/models/YOUR_MODEL’
headers = {‘Authorization’: ‘Bearer YOUR_HUGGING_FACE_API_KEY’}
response = requests.post(model_endpoint, headers=headers, json={“inputs”: ingredients})
if response.status_code == 200:return jsonify(response.json())
else:
return jsonify({“error”: “Failed to generate recipe”}), 500
if __name__ == ‘__main__’:app.run(debug=True)
This Flask app takes ingredients as input, sends them to Hugging Face’s recipe generation model, and returns a list of suggested recipes.
Connecting Next.js to the Flask API
Now, let’s create an interface in Next.js that allows users to request recipe suggestions based on their inventory:
// components/RecipeGenerator.js
import { useState } from 'react';
import axios from 'axios';
import { Button } from '@mui/material';
export default function RecipeGenerator({ inventory }) {const [recipe, setRecipe] = useState(”);
const generateRecipe = async () => {try {
const response = await axios.post(‘http://localhost:5000/generate_recipe’, { ingredients: inventory });
setRecipe(response.data);
} catch (error) {
console.error(‘Error generating recipe:’, error);
}
};
return (<div>
<Button variant=“contained” color=“primary” onClick={generateRecipe}>
Generate Recipe
</Button>
{recipe && <div><h3>Recipe Suggestion</h3><p>{recipe}</p></div>}
</div>
);
}
Integrate this into the main page:
// pages/index.js
import RecipeGenerator from '../components/RecipeGenerator';
export default function Home() {// … existing code
return (<div>
<h1>Food Inventory Management</h1>
<FoodItemForm addFoodItem={addFoodItem} />
<FoodInventory inventory={inventory} />
<RecipeGenerator inventory={inventory} />
</div>
);
}
Conclusion
By combining Next.js, Material-UI, Firebase, Flask, and Hugging Face, we have successfully built a Food Inventory Management App that allows users to input and track food items, store this data in Firebase, and generate recipe suggestions using AI models.
This project highlights the versatility and power of modern web development frameworks and machine learning APIs. The frontend ensures a responsive and user-friendly interface, while Firebase provides robust backend support. Flask and Hugging Face integration further enhance the app by introducing AI-based recipe generation, making it a comprehensive solution for anyone looking to streamline their meal planning and food inventory management.
The app can be further expanded to include features like expiration date tracking, nutritional information, or shopping list generation, making it a valuable tool for both home cooks and professional kitchens alike. The integration of AI allows the app to become a smart kitchen assistant, helping users optimize their ingredients and reduce waste.