mirror of
https://github.com/sstent/foodplanner.git
synced 2026-01-25 11:11:36 +00:00
updated the tracker to have more features
This commit is contained in:
@@ -280,10 +280,32 @@ async def update_tracked_food(request: Request, data: dict = Body(...), db: Sess
|
|||||||
try:
|
try:
|
||||||
tracked_food_id = data.get("tracked_food_id")
|
tracked_food_id = data.get("tracked_food_id")
|
||||||
quantity = float(data.get("quantity", 1.0))
|
quantity = float(data.get("quantity", 1.0))
|
||||||
|
is_custom = data.get("is_custom", False)
|
||||||
|
|
||||||
logging.info(f"DEBUG: Updating tracked food {tracked_food_id} quantity to {quantity}")
|
logging.info(f"DEBUG: Updating tracked food {tracked_food_id} quantity to {quantity}")
|
||||||
|
|
||||||
tracked_food = db.query(TrackedMealFood).filter(TrackedMealFood.id == tracked_food_id).first()
|
if is_custom:
|
||||||
|
tracked_food = db.query(TrackedMealFood).filter(TrackedMealFood.id == tracked_food_id).first()
|
||||||
|
else:
|
||||||
|
# It's a MealFood, we need to create a TrackedMealFood for it
|
||||||
|
meal_food = db.query(MealFood).filter(MealFood.id == tracked_food_id).first()
|
||||||
|
if not meal_food:
|
||||||
|
return {"status": "error", "message": "Meal food not found"}
|
||||||
|
|
||||||
|
tracked_meal = db.query(TrackedMeal).filter(TrackedMeal.meal_id == meal_food.meal_id).first()
|
||||||
|
if not tracked_meal:
|
||||||
|
return {"status": "error", "message": "Tracked meal not found"}
|
||||||
|
|
||||||
|
tracked_food = TrackedMealFood(
|
||||||
|
tracked_meal_id=tracked_meal.id,
|
||||||
|
food_id=meal_food.food_id,
|
||||||
|
quantity=quantity
|
||||||
|
)
|
||||||
|
db.add(tracked_food)
|
||||||
|
|
||||||
|
# We can now remove the original MealFood to avoid duplication
|
||||||
|
db.delete(meal_food)
|
||||||
|
|
||||||
if not tracked_food:
|
if not tracked_food:
|
||||||
return {"status": "error", "message": "Tracked food not found"}
|
return {"status": "error", "message": "Tracked food not found"}
|
||||||
|
|
||||||
@@ -456,6 +478,33 @@ async def remove_food_from_tracked_meal(meal_food_id: int, db: Session = Depends
|
|||||||
logging.error(f"DEBUG: Error removing food from tracked meal: {e}")
|
logging.error(f"DEBUG: Error removing food from tracked meal: {e}")
|
||||||
return {"status": "error", "message": str(e)}
|
return {"status": "error", "message": str(e)}
|
||||||
|
|
||||||
|
@router.delete("/tracker/remove_custom_food_from_tracked_meal/{tracked_meal_food_id}")
|
||||||
|
async def remove_custom_food_from_tracked_meal(tracked_meal_food_id: int, db: Session = Depends(get_db)):
|
||||||
|
"""Remove a custom food from a tracked meal"""
|
||||||
|
try:
|
||||||
|
tracked_meal_food = db.query(TrackedMealFood).filter(TrackedMealFood.id == tracked_meal_food_id).first()
|
||||||
|
if not tracked_meal_food:
|
||||||
|
raise HTTPException(status_code=404, detail="Tracked meal food not found")
|
||||||
|
|
||||||
|
# Mark the tracked day as modified
|
||||||
|
tracked_meal = tracked_meal_food.tracked_meal
|
||||||
|
if tracked_meal:
|
||||||
|
tracked_meal.tracked_day.is_modified = True
|
||||||
|
|
||||||
|
db.delete(tracked_meal_food)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return {"status": "success"}
|
||||||
|
|
||||||
|
except HTTPException as he:
|
||||||
|
db.rollback()
|
||||||
|
logging.error(f"DEBUG: HTTP Error removing custom food from tracked meal: {he.detail}")
|
||||||
|
return {"status": "error", "message": he.detail}
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
logging.error(f"DEBUG: Error removing custom food from tracked meal: {e}")
|
||||||
|
return {"status": "error", "message": str(e)}
|
||||||
|
|
||||||
@router.post("/tracker/save_as_new_meal")
|
@router.post("/tracker/save_as_new_meal")
|
||||||
async def save_as_new_meal(data: dict = Body(...), db: Session = Depends(get_db)):
|
async def save_as_new_meal(data: dict = Body(...), db: Session = Depends(get_db)):
|
||||||
"""Save an edited tracked meal as a new meal/variant"""
|
"""Save an edited tracked meal as a new meal/variant"""
|
||||||
|
|||||||
@@ -357,10 +357,13 @@
|
|||||||
const foodDiv = document.createElement('div');
|
const foodDiv = document.createElement('div');
|
||||||
foodDiv.className = 'd-flex justify-content-between align-items-center mb-2 p-2 bg-light rounded';
|
foodDiv.className = 'd-flex justify-content-between align-items-center mb-2 p-2 bg-light rounded';
|
||||||
foodDiv.innerHTML = `
|
foodDiv.innerHTML = `
|
||||||
<span>${food.quantity} × ${food.food_name}</span>
|
<div class="input-group">
|
||||||
<button class="btn btn-sm btn-outline-danger" onclick="removeFoodFromTrackedMeal(${food.id})">
|
<input type="number" step="0.01" class="form-control" value="${food.quantity}" data-food-id="${food.id}" data-is-custom="${food.is_custom}">
|
||||||
<i class="bi bi-trash"></i>
|
<span class="input-group-text">${food.food_name}</span>
|
||||||
</button>
|
<button class="btn btn-outline-danger" onclick="removeFoodFromTrackedMeal(${food.id}, ${food.is_custom})">
|
||||||
|
<i class="bi bi-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
container.appendChild(foodDiv);
|
container.appendChild(foodDiv);
|
||||||
});
|
});
|
||||||
@@ -404,10 +407,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove food from tracked meal
|
// Remove food from tracked meal
|
||||||
async function removeFoodFromTrackedMeal(mealFoodId) {
|
async function removeFoodFromTrackedMeal(foodId, isCustom) {
|
||||||
if (confirm('Remove this food from the tracked meal?')) {
|
if (confirm('Remove this food from the tracked meal?')) {
|
||||||
|
const url = isCustom ? `/tracker/remove_custom_food_from_tracked_meal/${foodId}` : `/tracker/remove_food_from_tracked_meal/${foodId}`;
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/tracker/remove_food_from_tracked_meal/${mealFoodId}`, {
|
const response = await fetch(url, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -425,37 +429,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save tracked meal changes
|
// Save tracked meal changes (No longer needed as updates are real-time)
|
||||||
async function saveTrackedMeal() {
|
async function saveTrackedMeal() {
|
||||||
const trackedMealId = document.getElementById('editTrackedMealId').value;
|
bootstrap.Modal.getInstance(document.getElementById('editTrackedMealModal')).hide();
|
||||||
const inputs = document.querySelectorAll('#editMealFoodsList input[type="number"]');
|
location.reload();
|
||||||
|
|
||||||
const updates = [];
|
|
||||||
inputs.forEach(input => {
|
|
||||||
updates.push({
|
|
||||||
tracked_food_id: input.dataset.foodId,
|
|
||||||
quantity: parseFloat(input.value)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('/tracker/update_tracked_meal', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ tracked_meal_id: trackedMealId, updates: updates })
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.status === 'success') {
|
|
||||||
bootstrap.Modal.getInstance(document.getElementById('editTrackedMealModal')).hide();
|
|
||||||
location.reload();
|
|
||||||
} else {
|
|
||||||
alert('Error: ' + result.message);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
alert('Error: ' + error.message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save as new meal
|
// Save as new meal
|
||||||
@@ -469,7 +446,7 @@
|
|||||||
const foods = [];
|
const foods = [];
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
foods.push({
|
foods.push({
|
||||||
food_id: input.dataset.foodId,
|
food_id: parseInt(input.dataset.foodId),
|
||||||
quantity: parseFloat(input.value)
|
quantity: parseFloat(input.value)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user