Untitled
```main:javascript function MainComponent() { const [meals, setMeals] = useState([]); const [food, setFood] = useState(""); const [calories, setCalories] = useState(""); const [dailyGoal] = useState(2000); const [scanning, setScanning] = useState(false); const [error, setError] = useState(null); const [upload, { loading }] = useUpload(); const [suggestions, setSuggestions] = useState([]); const [loadingSuggestions, setLoadingSuggestions] = useState(false); const handleSubmit = (e) => { e.preventDefault(); if (food && calories) { setMeals([...meals, { food, calories: parseInt(calories), protein: 0 }]); setFood(""); setCalories(""); } }; const handleFoodInput = async (value) => { setFood(value); if (value.length > 2) { setLoadingSuggestions(true); try { const response = await fetch("/integrations/chat-gpt/conversationgpt4", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ messages: [{ role: "user", content: `Suggest 3 similar food items to "${value}" with their calories and protein content. Format as JSON array: [{food: string, calories: number, protein: number}]` }], json_schema: { name: "food_suggestions", schema: { type: "object", properties: { suggestions: { type: "array", items: { type: "object", properties: { food: { type: "string" }, calories: { type: "number" }, protein: { type: "number" } }, required: ["food", "calories", "protein"], additionalProperties: false } } }, required: ["suggestions"], additionalProperties: false } } }) }); const data = await response.json(); const parsedSuggestions = JSON.parse(data.choices[0].message.content); setSuggestions(parsedSuggestions.suggestions); } catch (err) { console.error(err); setSuggestions([]); } finally { setLoadingSuggestions(false); } } else { setSuggestions([]); } }; const handleImageUpload = async (e) => { const file = e.target.files[0]; if (!file) return; try { setScanning(true); setError(null); const { url } = await upload({ file }); const response = await GPT4Vision.analyze({ image: url, prompt: "Analyze this food image and provide the food name, estimated calories, and protein content in grams. Format as JSON: {food: string, calories: number, protein: number}", }); const foodData = JSON.parse(response); setMeals([...meals, foodData]); } catch (err) { setError("Couldn't analyze the food. Please try again."); } finally { setScanning(false); } }; const handleSuggestionClick = (suggestion) => { setFood(suggestion.food); setCalories(suggestion.calories.toString()); setSuggestions([]); }; const totalCalories = meals.reduce((sum, meal) => sum + meal.calories, 0); const totalProtein = meals.reduce( (sum, meal) => sum + (meal.protein || 0), 0, ); return ( <div className="min-h-screen bg-gray-100 p-4"> <div className="max-w-md mx-auto bg-white rounded-lg shadow-lg p-6"> <h1 className="text-2xl font-bold text-center mb-6 font-roboto"> Daily Calories Tracker </h1> <div className="mb-6 bg-gray-200 rounded-lg p-4"> <div className="flex justify-between items-center flex-wrap gap-4"> <div> <p className="font-semibold">Daily Goal:</p> <p className="text-xl">{dailyGoal} calories</p> </div> <div> <p className="font-semibold">Consumed:</p> <p className="text-xl">{totalCalories} calories</p> </div> <div> <p className="font-semibold">Protein:</p> <p className="text-xl">{totalProtein}g</p> </div> </div> </div> <div className="mb-6"> <label className="block w-full"> <div className="mb-2 text-center"> <i className="fas fa-camera text-xl mr-2"></i> Scan Food </div> <input type="file" accept="image/*" capture="environment" onChange={handleImageUpload} className="hidden" /> <div className="w-full bg-green-500 text-white py-3 rounded text-center cursor-pointer hover:bg-green-600 transition-colors"> {scanning ? "Analyzing..." : "Take Photo"} </div> </label> {error && ( <p className="text-red-500 text-sm mt
Leave a Comment