Meal Tracker - full feature set with auth, favorites, admin panel

This commit is contained in:
Otto
2026-03-30 21:44:46 -04:00
parent 39b66bbb5a
commit e60aaa111a
20 changed files with 1422 additions and 622 deletions

View File

@@ -1,53 +1,39 @@
import express from 'express';
const router = express.Router();
import axios from 'axios';
const OPENFOODFACTS_API = 'https://world.openfoodfacts.org/cgi/search.pl';
// GET /api/foods/search?q=
router.get('/search', async (req, res) => {
try {
export default function setupRoutes(app) {
app.get('/api/foods/search', async (req, res) => {
const { q } = req.query;
if (!q || q.trim().length < 2) {
return res.status(400).json({ error: 'Search query must be at least 2 characters' });
if (!q) {
return res.json([]);
}
const params = new URLSearchParams({
search_terms: q,
search_simple: 1,
action: 'process',
json: 1,
page_size: 20,
fields: 'product_name,brands,nutriments,serving_size'
});
const response = await fetch(`${OPENFOODFACTS_API}?${params}`, {
headers: {
'User-Agent': 'MealTracker/1.0'
}
});
if (!response.ok) {
throw new Error(`OpenFoodFacts API error: ${response.status}`);
}
const data = await response.json();
const foods = (data.products || []).map(product => ({
name: product.product_name || 'Unknown',
brand: product.brands || null,
calories: product.nutriments?.['energy-kcal_100g'] ?? product.nutriments?.['energy-kcal'] ?? 0,
protein: product.nutriments?.proteins_100g ?? product.nutriments?.proteins ?? 0,
carbs: product.nutriments?.carbohydrates_100g ?? product.nutriments?.carbohydrates ?? 0,
fat: product.nutriments?.fat_100g ?? product.nutriments?.fat ?? 0,
serving_size: product.serving_size || '100g'
})).filter(f => f.name !== 'Unknown');
res.json(foods);
} catch (err) {
console.error('Food search error:', err);
res.status(500).json({ error: err.message });
}
});
export default router;
try {
const response = await axios.get(OPENFOODFACTS_API, {
params: {
search_terms: q,
search_simple: 1,
action: 'process',
json: 1,
page_size: 10
}
});
const products = response.data.products || [];
const foods = products.map(p => ({
name: p.product_name || p.product_name_en || 'Unknown',
calories: p.nutriments?.['energy-kcal_100g'] || 0,
protein: p.nutriments?.proteins_100g || 0,
carbs: p.nutriments?.carbohydrates_100g || 0,
fat: p.nutriments?.fat_100g || 0
})).filter(f => f.name !== 'Unknown' && f.calories > 0);
res.json(foods);
} catch (err) {
console.error(err);
res.status(503).json({ error: 'Food search unavailable' });
}
});
}