90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
from datetime import date, timedelta
|
|
from fastapi import APIRouter, Request, Depends
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlalchemy import select, desc
|
|
|
|
from app.models.base import async_session
|
|
from app.models.user import User
|
|
from app.models.workout import Phase, Workout
|
|
from app.models.checkin import Checkin
|
|
from app.models.measurement import Measurement, MeasurementType
|
|
from app.auth import get_current_user
|
|
|
|
router = APIRouter()
|
|
templates = Jinja2Templates(directory="app/templates")
|
|
|
|
|
|
def _week_bounds() -> tuple[str, str]:
|
|
today = date.today()
|
|
monday = today - timedelta(days=today.weekday())
|
|
sunday = monday + timedelta(days=6)
|
|
return monday.isoformat(), sunday.isoformat()
|
|
|
|
|
|
@router.get("/", response_class=HTMLResponse)
|
|
async def root_redirect():
|
|
from fastapi.responses import RedirectResponse
|
|
return RedirectResponse(url="/dashboard")
|
|
|
|
|
|
@router.get("/dashboard", response_class=HTMLResponse)
|
|
async def dashboard(request: Request, user: User = Depends(get_current_user)):
|
|
week_start, week_end = _week_bounds()
|
|
|
|
async with async_session() as session:
|
|
result = await session.execute(
|
|
select(Workout)
|
|
.where(Workout.user_id == user.id)
|
|
.order_by(desc(Workout.date))
|
|
.limit(5)
|
|
)
|
|
recent_workouts = result.scalars().all()
|
|
|
|
result = await session.execute(
|
|
select(Checkin)
|
|
.where(Checkin.user_id == user.id)
|
|
.order_by(desc(Checkin.date))
|
|
.limit(1)
|
|
)
|
|
latest_checkin = result.scalar_one_or_none()
|
|
|
|
result = await session.execute(
|
|
select(Phase).order_by(Phase.start_date.desc().nulls_last()).limit(1)
|
|
)
|
|
current_phase = result.scalar_one_or_none()
|
|
|
|
result = await session.execute(
|
|
select(Workout)
|
|
.where(
|
|
Workout.user_id == user.id,
|
|
Workout.date >= week_start,
|
|
Workout.date <= week_end,
|
|
)
|
|
.order_by(Workout.date)
|
|
)
|
|
this_week = result.scalars().all()
|
|
|
|
result = await session.execute(
|
|
select(Measurement)
|
|
.join(MeasurementType, Measurement.measurement_type_id == MeasurementType.id)
|
|
.where(
|
|
Measurement.user_id == user.id,
|
|
MeasurementType.name == "Weight",
|
|
)
|
|
.order_by(desc(Measurement.date))
|
|
.limit(1)
|
|
)
|
|
latest_weight = result.scalar_one_or_none()
|
|
|
|
return templates.TemplateResponse(request, "dashboard.html", {
|
|
"user": user,
|
|
"recent_workouts": recent_workouts,
|
|
"latest_checkin": latest_checkin,
|
|
"current_phase": current_phase,
|
|
"this_week": this_week,
|
|
"week_start": week_start,
|
|
"week_end": week_end,
|
|
"latest_weight": latest_weight.value if latest_weight else None,
|
|
})
|