Event layout page update.

This commit is contained in:
2026-01-11 15:21:17 -06:00
parent e0af183086
commit e50b2f31d3
13 changed files with 1460 additions and 183 deletions

View File

@ -6,6 +6,7 @@ from app.models.sport_event import SportEvent, SportType, EventStatus
from app.models.spread_bet import SpreadBet, SpreadBetStatus, TeamSide
from app.models.admin_settings import AdminSettings
from app.models.match_comment import MatchComment
from app.models.event_comment import EventComment
from app.models.gamification import (
UserStats,
Achievement,
@ -40,6 +41,7 @@ __all__ = [
"TeamSide",
"AdminSettings",
"MatchComment",
"EventComment",
# Gamification
"UserStats",
"Achievement",

View File

@ -0,0 +1,18 @@
from sqlalchemy import String, DateTime, ForeignKey, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from datetime import datetime
from app.database import Base
class EventComment(Base):
__tablename__ = "event_comments"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
event_id: Mapped[int] = mapped_column(ForeignKey("sport_events.id"))
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
content: Mapped[str] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
# Relationships
event: Mapped["SportEvent"] = relationship()
user: Mapped["User"] = relationship()

View File

@ -6,9 +6,11 @@ from typing import List
from datetime import datetime
from app.database import get_db
from app.models import User, SportEvent, SpreadBet, AdminSettings, EventStatus, SpreadBetStatus, TeamSide
from app.models import User, SportEvent, SpreadBet, AdminSettings, EventStatus, SpreadBetStatus, TeamSide, EventComment
from app.schemas.sport_event import SportEvent as SportEventSchema, SportEventWithBets
from app.schemas.event_comment import EventComment as EventCommentSchema, EventCommentCreate, EventCommentsResponse
from app.routers.auth import get_current_user
from app.routers.websocket import broadcast_to_event
router = APIRouter(prefix="/api/v1/sport-events", tags=["sport-events"])
@ -220,3 +222,104 @@ async def get_event_with_grid(
"updated_at": event.updated_at.isoformat(),
"spread_grid": spread_grid
}
@router.get("/{event_id}/comments", response_model=EventCommentsResponse)
async def get_event_comments(
event_id: int,
skip: int = 0,
limit: int = 50,
db: AsyncSession = Depends(get_db)
):
"""Get comments for an event - public access."""
# Verify event exists
event_result = await db.execute(
select(SportEvent).where(SportEvent.id == event_id)
)
event = event_result.scalar_one_or_none()
if not event:
raise HTTPException(status_code=404, detail="Event not found")
# Get comments with user info
result = await db.execute(
select(EventComment)
.options(selectinload(EventComment.user))
.where(EventComment.event_id == event_id)
.order_by(EventComment.created_at.asc())
.offset(skip)
.limit(limit)
)
comments = result.scalars().all()
# Get total count
count_result = await db.execute(
select(EventComment).where(EventComment.event_id == event_id)
)
total = len(count_result.scalars().all())
return EventCommentsResponse(
comments=[
EventCommentSchema(
id=c.id,
event_id=c.event_id,
user_id=c.user_id,
username=c.user.username,
content=c.content,
created_at=c.created_at
)
for c in comments
],
total=total
)
@router.post("/{event_id}/comments", response_model=EventCommentSchema)
async def add_event_comment(
event_id: int,
comment_data: EventCommentCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""Add a comment to an event - requires authentication."""
# Verify event exists
event_result = await db.execute(
select(SportEvent).where(SportEvent.id == event_id)
)
event = event_result.scalar_one_or_none()
if not event:
raise HTTPException(status_code=404, detail="Event not found")
# Create comment
comment = EventComment(
event_id=event_id,
user_id=current_user.id,
content=comment_data.content
)
db.add(comment)
await db.commit()
await db.refresh(comment)
comment_response = EventCommentSchema(
id=comment.id,
event_id=comment.event_id,
user_id=comment.user_id,
username=current_user.username,
content=comment.content,
created_at=comment.created_at
)
# Broadcast new comment to event subscribers
await broadcast_to_event(
event_id,
"new_comment",
{
"id": comment.id,
"event_id": comment.event_id,
"user_id": comment.user_id,
"username": current_user.username,
"content": comment.content,
"created_at": comment.created_at.isoformat()
}
)
return comment_response

View File

@ -0,0 +1,24 @@
from pydantic import BaseModel, Field
from datetime import datetime
from typing import List
class EventCommentCreate(BaseModel):
content: str = Field(..., min_length=1, max_length=500)
class EventComment(BaseModel):
id: int
event_id: int
user_id: int
username: str
content: str
created_at: datetime
class Config:
from_attributes = True
class EventCommentsResponse(BaseModel):
comments: List[EventComment]
total: int