mirror of
https://github.com/escalante29/healthy-fit.git
synced 2026-03-21 12:28:46 +01:00
Migrate frontend to TypeScript and extend user profile
Converted frontend codebase from JavaScript to TypeScript, including pages, components, and context. Added new layout and UI kit components. Updated backend user model and schemas to support profile fields (firstname, lastname, age, gender, height, weight, unit_preference) and added endpoints for reading/updating current user. Introduced food log listing endpoint and migration script for user table. Updated dependencies and build configs for TypeScript and Tailwind v4.
This commit is contained in:
@@ -61,9 +61,7 @@ class NutritionModule(dspy.Module):
|
||||
pred = self.extract(description=description)
|
||||
|
||||
# Assertion: Check Macro Consistency
|
||||
calc_cals = (
|
||||
(pred.nutritional_info.protein * 4) + (pred.nutritional_info.carbs * 4) + (pred.nutritional_info.fats * 9)
|
||||
)
|
||||
# calc_cals calculation removed as dspy.Suggest is disabled
|
||||
|
||||
# dspy.Suggest is not available in dspy>=3.1.0
|
||||
# dspy.Suggest(
|
||||
@@ -78,9 +76,7 @@ class NutritionModule(dspy.Module):
|
||||
pred = self.analyze_image(image=image, description=description)
|
||||
|
||||
# Assertion: Check Macro Consistency
|
||||
calc_cals = (
|
||||
(pred.nutritional_info.protein * 4) + (pred.nutritional_info.carbs * 4) + (pred.nutritional_info.fats * 9)
|
||||
)
|
||||
# calc_cals calculation removed as dspy.Suggest is disabled
|
||||
|
||||
# dspy.Suggest is not available in dspy>=3.1.0
|
||||
# dspy.Suggest(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import litellm
|
||||
import dspy
|
||||
from typing import Any
|
||||
|
||||
import litellm
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
|
||||
from pydantic import BaseModel
|
||||
from sqlmodel import Session
|
||||
@@ -70,3 +69,25 @@ def log_food(
|
||||
session.commit()
|
||||
session.refresh(food_log)
|
||||
return food_log
|
||||
|
||||
|
||||
@router.get("/logs", response_model=list[FoodLog])
|
||||
def read_logs(
|
||||
current_user: deps.CurrentUser,
|
||||
session: Session = Depends(deps.get_session),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
) -> Any:
|
||||
"""
|
||||
Get food logs for current user.
|
||||
"""
|
||||
from sqlmodel import select
|
||||
|
||||
statement = (
|
||||
select(FoodLog)
|
||||
.where(FoodLog.user_id == current_user.id)
|
||||
.order_by(FoodLog.timestamp.desc())
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
)
|
||||
return session.exec(statement).all()
|
||||
|
||||
@@ -6,7 +6,7 @@ from sqlmodel import Session, select
|
||||
from app.api import deps
|
||||
from app.core import security
|
||||
from app.models.user import User
|
||||
from app.schemas.user import UserCreate, UserRead
|
||||
from app.schemas.user import UserCreate, UserRead, UserUpdate
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -36,3 +36,31 @@ def create_user(
|
||||
session.commit()
|
||||
session.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@router.get("/me", response_model=UserRead)
|
||||
def read_user_me(
|
||||
current_user: deps.CurrentUser,
|
||||
) -> Any:
|
||||
"""
|
||||
Get current user.
|
||||
"""
|
||||
return current_user
|
||||
|
||||
|
||||
@router.put("/me", response_model=UserRead)
|
||||
def update_user_me(
|
||||
*,
|
||||
session: Session = Depends(deps.get_session),
|
||||
user_in: UserUpdate,
|
||||
current_user: deps.CurrentUser,
|
||||
) -> Any:
|
||||
"""
|
||||
Update own user.
|
||||
"""
|
||||
user_data = user_in.model_dump(exclude_unset=True)
|
||||
current_user.sqlmodel_update(user_data)
|
||||
session.add(current_user)
|
||||
session.commit()
|
||||
session.refresh(current_user)
|
||||
return current_user
|
||||
|
||||
@@ -9,4 +9,14 @@ class User(SQLModel, table=True):
|
||||
username: str = Field(index=True, unique=True)
|
||||
email: str = Field(index=True, unique=True)
|
||||
password_hash: str
|
||||
|
||||
# Profile Info
|
||||
firstname: Optional[str] = None
|
||||
lastname: Optional[str] = None
|
||||
age: Optional[int] = None
|
||||
gender: Optional[str] = None
|
||||
height: Optional[float] = None
|
||||
weight: Optional[float] = None
|
||||
unit_preference: str = Field(default="metric") # "metric" or "imperial"
|
||||
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
@@ -14,9 +14,23 @@ class UserCreate(UserBase):
|
||||
|
||||
class UserRead(UserBase):
|
||||
id: int
|
||||
firstname: Optional[str] = None
|
||||
lastname: Optional[str] = None
|
||||
age: Optional[int] = None
|
||||
gender: Optional[str] = None
|
||||
height: Optional[float] = None
|
||||
weight: Optional[float] = None
|
||||
unit_preference: str = "metric"
|
||||
|
||||
|
||||
class UserUpdate(SQLModel):
|
||||
email: Optional[str] = None
|
||||
username: Optional[str] = None
|
||||
password: Optional[str] = None
|
||||
firstname: Optional[str] = None
|
||||
lastname: Optional[str] = None
|
||||
age: Optional[int] = None
|
||||
gender: Optional[str] = None
|
||||
height: Optional[float] = None
|
||||
weight: Optional[float] = None
|
||||
unit_preference: Optional[str] = None
|
||||
|
||||
Reference in New Issue
Block a user