from typing import Annotated, Optional from fastapi import FastAPI, Depends, Request from sqlalchemy.orm import Session from starlette import status from starlette.middleware.base import BaseHTTPMiddleware from starlette.staticfiles import StaticFiles import models from auth import get_db, get_current_user, router as auth_router from config import templates, ACCESS_TOKEN_EXPIRE_MINUTES from models import Property from properties import router as properties_router app = FastAPI() app.include_router(auth_router) app.include_router(properties_router) app.mount("/static", StaticFiles(directory="static"), name="static") models.Base.metadata.create_all(bind=__import__("database", fromlist=["engine"]).engine) class RefreshTokenMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): response = await call_next(request) new_token = getattr(request.state, "new_access_token", None) if new_token: response.set_cookie( "access_token", new_token, httponly=True, max_age=ACCESS_TOKEN_EXPIRE_MINUTES * 60, samesite="lax", ) return response app.add_middleware(RefreshTokenMiddleware) db_dependency = Annotated[Session, Depends(get_db)] user_dependency = Annotated[Optional[dict], Depends(get_current_user)] @app.get("/", status_code=status.HTTP_200_OK) async def homepage(request: Request, db: db_dependency, user: user_dependency): # Show featured properties; if none are featured, show the latest listings featured = ( db.query(Property) .filter(Property.is_featured == True, Property.status == "active") .limit(6) .all() ) if not featured: featured = ( db.query(Property) .filter(Property.status == "active") .order_by(Property.created_at.desc()) .limit(6) .all() ) for prop in featured: prop.primary_image = next( (img for img in prop.images if img.is_primary), prop.images[0] if prop.images else None, ) return templates.TemplateResponse(request, "index.html", { "user": user, "properties": featured, })