From 6de9c580a5a8ecdb0eaa17d8e393d377cd847c9a Mon Sep 17 00:00:00 2001 From: sstent Date: Tue, 30 Sep 2025 06:04:19 -0700 Subject: [PATCH] added chart --- app/api/routes/charts.py | 49 +++++++++++++++++ main.py | 3 +- templates/base.html | 5 ++ templates/charts.html | 109 +++++++++++++++++++++++++++++++++++++ tests/test_charts.py | 113 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 app/api/routes/charts.py create mode 100644 templates/charts.html create mode 100644 tests/test_charts.py diff --git a/app/api/routes/charts.py b/app/api/routes/charts.py new file mode 100644 index 0000000..f125dd2 --- /dev/null +++ b/app/api/routes/charts.py @@ -0,0 +1,49 @@ +from fastapi import APIRouter, Depends, Query +from sqlalchemy.orm import Session +from datetime import date, timedelta +from typing import List +from app.database import get_db, TrackedDay, TrackedMeal, calculate_day_nutrition_tracked + +router = APIRouter(tags=["charts"]) + +@router.get("/charts", response_class=HTMLResponse) +async def charts_page(request: Request, person: str = "Sarah", db: Session = Depends(get_db)): + """Render the charts page""" + from main import templates + return templates.TemplateResponse("charts.html", { + "request": request, + "person": person + }) + +@router.get("/api/charts", response_model=List[dict]) +async def get_charts_data( + person: str = Query(..., description="Person name (e.g., Sarah)"), + days: int = Query(7, description="Number of past days to fetch data for", ge=1, le=30), + db: Session = Depends(get_db) +): + """ + Get daily calorie data for the last N days for a person. + Returns list of {"date": "YYYY-MM-DD", "calories": float} sorted by date descending. + """ + + end_date = date.today() + start_date = end_date - timedelta(days=days - 1) + + tracked_days = db.query(TrackedDay).filter( + TrackedDay.person == person, + TrackedDay.date >= start_date, + TrackedDay.date <= end_date + ).order_by(TrackedDay.date.desc()).all() + + chart_data = [] + for tracked_day in tracked_days: + tracked_meals = db.query(TrackedMeal).filter( + TrackedMeal.tracked_day_id == tracked_day.id + ).all() + day_totals = calculate_day_nutrition_tracked(tracked_meals, db) + chart_data.append({ + "date": tracked_day.date.isoformat(), + "calories": round(day_totals.get("calories", 0), 2) + }) + + return chart_data \ No newline at end of file diff --git a/main.py b/main.py index 3491cc1..30dee51 100644 --- a/main.py +++ b/main.py @@ -50,7 +50,7 @@ async def lifespan(app: FastAPI): app = FastAPI(title="Meal Planner", lifespan=lifespan) templates = Jinja2Templates(directory="templates") -from app.api.routes import foods, meals, plans, templates as templates_router, weekly_menu, tracker, admin, export +from app.api.routes import foods, meals, plans, templates as templates_router, weekly_menu, tracker, admin, export, charts app.include_router(foods.router, tags=["foods"]) app.include_router(meals.router, tags=["meals"]) @@ -60,6 +60,7 @@ app.include_router(weekly_menu.router, tags=["weekly_menu"]) app.include_router(tracker.router, tags=["tracker"]) app.include_router(admin.router, tags=["admin"]) app.include_router(export.router, tags=["export"]) +app.include_router(charts.router, tags=["charts"]) # Add a logging middleware to see incoming requests @app.middleware("http") diff --git a/templates/base.html b/templates/base.html index 3d91d9d..53841b1 100644 --- a/templates/base.html +++ b/templates/base.html @@ -88,6 +88,11 @@ Tracker +