"""Meals blueprint — dashboard, responses, history.""" from datetime import date, datetime, timedelta from flask import ( Blueprint, render_template, request, redirect, url_for, session, flash, ) from models import get_dashboard_data, upsert_response, ensure_meal_periods meals_bp = Blueprint("meals", __name__) def login_required(f): """Decorator: redirect to login if not authenticated or session is stale.""" from functools import wraps @wraps(f) def wrapper(*args, **kwargs): if "user_id" not in session or "household_id" not in session: session.clear() return redirect(url_for("auth.login")) return f(*args, **kwargs) return wrapper @meals_bp.route("/") def index(): if "user_id" in session: return redirect(url_for("meals.dashboard")) return redirect(url_for("auth.login")) @meals_bp.route("/dashboard") @login_required def dashboard(): today = date.today() household_id = session["household_id"] # Allow viewing other dates via query param date_str = request.args.get("date") if date_str: try: today = datetime.strptime(date_str, "%Y-%m-%d").date() except ValueError: flash("Invalid date format. Use YYYY-MM-DD.", "error") if household_id is None: session.clear() return redirect(url_for("auth.login")) data = get_dashboard_data(today, household_id) return render_template( "dashboard.html", dashboard=data, viewing_date=today, today=date.today(), prev_date=today - timedelta(days=1), next_date=today + timedelta(days=1), ) @meals_bp.route("/respond", methods=["POST"]) @login_required def respond(): meal_type = request.form.get("meal_type", "").strip() status = request.form.get("status", "").strip() date_str = request.form.get("date", date.today().isoformat()) if meal_type not in ("lunch", "dinner"): flash("Invalid meal type.", "error") return redirect(url_for("meals.dashboard")) if status not in ("yes", "no"): flash("Invalid status.", "error") return redirect(url_for("meals.dashboard")) try: target_date = datetime.strptime(date_str, "%Y-%m-%d").date() except ValueError: flash("Invalid date.", "error") return redirect(url_for("meals.dashboard")) if target_date < date.today(): flash("Cannot change responses for past dates.", "error") return redirect(url_for("meals.dashboard")) periods = ensure_meal_periods(target_date) period = next((p for p in periods if p["meal_type"] == meal_type), None) if period is None: flash("Meal period not found.", "error") return redirect(url_for("meals.dashboard")) upsert_response(session["user_id"], period["id"], status) return redirect(url_for("meals.dashboard")) @meals_bp.route("/history") @login_required def history(): date_str = request.args.get("date", date.today().isoformat()) try: target_date = datetime.strptime(date_str, "%Y-%m-%d").date() except ValueError: target_date = date.today() data = get_dashboard_data(target_date, session["household_id"]) return render_template( "dashboard.html", dashboard=data, viewing_date=target_date, today=date.today(), prev_date=target_date - timedelta(days=1), next_date=target_date + timedelta(days=1), history_mode=True, )