Event layout page update.
This commit is contained in:
@ -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",
|
||||
|
||||
18
backend/app/models/event_comment.py
Normal file
18
backend/app/models/event_comment.py
Normal 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()
|
||||
@ -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
|
||||
|
||||
24
backend/app/schemas/event_comment.py
Normal file
24
backend/app/schemas/event_comment.py
Normal 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
|
||||
Reference in New Issue
Block a user