Untitled
unknown
plain_text
a year ago
5.0 kB
6
Indexable
```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 mtEditor is loading...
Leave a Comment