""" API Routes para el Dashboard. """ from datetime import datetime, timedelta from typing import Optional from fastapi import APIRouter, Depends, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from sqlalchemy import func from app.core.database import get_db from app.models.post import Post from app.models.interaction import Interaction from app.models.user import User from app.api.routes.auth import get_current_user_from_cookie router = APIRouter() templates = Jinja2Templates(directory="dashboard/templates") def require_auth(request: Request, db: Session) -> Optional[User]: """Verificar autenticación. Retorna None si no está autenticado.""" return get_current_user_from_cookie(request, db) @router.get("/", response_class=HTMLResponse) async def dashboard_home(request: Request, db: Session = Depends(get_db)): """Página principal del dashboard.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) # Estadísticas now = datetime.utcnow() today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) week_start = today_start - timedelta(days=now.weekday()) stats = { "posts_today": db.query(Post).filter( Post.published_at >= today_start ).count(), "posts_week": db.query(Post).filter( Post.published_at >= week_start ).count(), "pending_approval": db.query(Post).filter( Post.status == "pending_approval" ).count(), "scheduled": db.query(Post).filter( Post.status == "scheduled" ).count(), "interactions_pending": db.query(Interaction).filter( Interaction.responded == False, Interaction.is_archived == False ).count() } # Posts pendientes pending_posts = db.query(Post).filter( Post.status == "pending_approval" ).order_by(Post.scheduled_at.asc()).limit(5).all() # Próximas publicaciones scheduled_posts = db.query(Post).filter( Post.status == "scheduled", Post.scheduled_at >= now ).order_by(Post.scheduled_at.asc()).limit(5).all() # Interacciones recientes recent_interactions = db.query(Interaction).filter( Interaction.responded == False ).order_by(Interaction.interaction_at.desc()).limit(5).all() # Posts publicados recientemente recent_published = db.query(Post).filter( Post.status == "published" ).order_by(Post.published_at.desc()).limit(5).all() return templates.TemplateResponse("index.html", { "request": request, "user": user.to_dict(), "stats": stats, "pending_posts": [p.to_dict() for p in pending_posts], "scheduled_posts": [p.to_dict() for p in scheduled_posts], "recent_interactions": [i.to_dict() for i in recent_interactions], "recent_published": [p.to_dict() for p in recent_published] }) @router.get("/compose", response_class=HTMLResponse) async def dashboard_compose(request: Request, db: Session = Depends(get_db)): """Página para crear nuevas publicaciones.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("compose.html", { "request": request, "user": user.to_dict() }) @router.get("/posts", response_class=HTMLResponse) async def dashboard_posts(request: Request, db: Session = Depends(get_db)): """Página de gestión de posts.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) posts = db.query(Post).order_by(Post.created_at.desc()).limit(50).all() return templates.TemplateResponse("posts.html", { "request": request, "user": user.to_dict(), "posts": [p.to_dict() for p in posts] }) @router.get("/calendar", response_class=HTMLResponse) async def dashboard_calendar(request: Request, db: Session = Depends(get_db)): """Página de calendario.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("calendar.html", { "request": request, "user": user.to_dict() }) @router.get("/interactions", response_class=HTMLResponse) async def dashboard_interactions(request: Request, db: Session = Depends(get_db)): """Página de interacciones.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) interactions = db.query(Interaction).filter( Interaction.is_archived == False ).order_by(Interaction.interaction_at.desc()).limit(50).all() return templates.TemplateResponse("interactions.html", { "request": request, "user": user.to_dict(), "interactions": [i.to_dict() for i in interactions] }) @router.get("/products", response_class=HTMLResponse) async def dashboard_products(request: Request, db: Session = Depends(get_db)): """Página de productos.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("products.html", { "request": request, "user": user.to_dict() }) @router.get("/services", response_class=HTMLResponse) async def dashboard_services(request: Request, db: Session = Depends(get_db)): """Página de servicios.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("services.html", { "request": request, "user": user.to_dict() }) @router.get("/settings", response_class=HTMLResponse) async def dashboard_settings(request: Request, db: Session = Depends(get_db)): """Página de configuración.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("settings.html", { "request": request, "user": user.to_dict() }) @router.get("/analytics", response_class=HTMLResponse) async def dashboard_analytics(request: Request, db: Session = Depends(get_db)): """Página de analytics.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("analytics.html", { "request": request, "user": user.to_dict() }) @router.get("/leads", response_class=HTMLResponse) async def dashboard_leads(request: Request, db: Session = Depends(get_db)): """Página de leads.""" user = require_auth(request, db) if not user: return RedirectResponse(url="/login", status_code=302) return templates.TemplateResponse("leads.html", { "request": request, "user": user.to_dict() })