from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List from app.db.base import get_db from app.models.user import User from app.models.event import Event, EventRegistration from app.schemas.event import ( EventCreate, EventUpdate, EventResponse, EventRegistrationResponse, ) from app.api.auth import get_current_user router = APIRouter() @router.post("/", response_model=EventResponse) def create_event( event: EventCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): db_event = Event(**event.dict(), created_by=current_user.id) db.add(db_event) db.commit() db.refresh(db_event) return db_event @router.get("/", response_model=List[EventResponse]) def get_events( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): events = db.query(Event).filter(Event.is_public).offset(skip).limit(limit).all() # Add additional info for each event for event in events: event.creator_name = f"{event.creator.first_name} {event.creator.last_name}" event.registered_count = ( db.query(EventRegistration) .filter(EventRegistration.event_id == event.id) .count() ) event.is_registered = ( db.query(EventRegistration) .filter( EventRegistration.event_id == event.id, EventRegistration.user_id == current_user.id, ) .first() is not None ) return events @router.get("/{event_id}", response_model=EventResponse) def get_event( event_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): event = db.query(Event).filter(Event.id == event_id).first() if event is None: raise HTTPException(status_code=404, detail="Event not found") event.creator_name = f"{event.creator.first_name} {event.creator.last_name}" event.registered_count = ( db.query(EventRegistration) .filter(EventRegistration.event_id == event.id) .count() ) event.is_registered = ( db.query(EventRegistration) .filter( EventRegistration.event_id == event.id, EventRegistration.user_id == current_user.id, ) .first() is not None ) return event @router.put("/{event_id}", response_model=EventResponse) def update_event( event_id: int, event_update: EventUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): event = db.query(Event).filter(Event.id == event_id).first() if event is None: raise HTTPException(status_code=404, detail="Event not found") if event.created_by != current_user.id and not current_user.is_admin: raise HTTPException( status_code=403, detail="Not authorized to update this event" ) for field, value in event_update.dict(exclude_unset=True).items(): setattr(event, field, value) db.commit() db.refresh(event) return event @router.delete("/{event_id}") def delete_event( event_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): event = db.query(Event).filter(Event.id == event_id).first() if event is None: raise HTTPException(status_code=404, detail="Event not found") if event.created_by != current_user.id and not current_user.is_admin: raise HTTPException( status_code=403, detail="Not authorized to delete this event" ) db.delete(event) db.commit() return {"message": "Event deleted successfully"} @router.post("/{event_id}/register", response_model=EventRegistrationResponse) def register_for_event( event_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): event = db.query(Event).filter(Event.id == event_id).first() if event is None: raise HTTPException(status_code=404, detail="Event not found") # Check if already registered existing_registration = ( db.query(EventRegistration) .filter( EventRegistration.event_id == event_id, EventRegistration.user_id == current_user.id, ) .first() ) if existing_registration: raise HTTPException(status_code=400, detail="Already registered for this event") # Check if event is full if event.max_attendees: current_count = ( db.query(EventRegistration) .filter(EventRegistration.event_id == event_id) .count() ) if current_count >= event.max_attendees: raise HTTPException(status_code=400, detail="Event is full") registration = EventRegistration(event_id=event_id, user_id=current_user.id) db.add(registration) db.commit() db.refresh(registration) registration.user_name = f"{current_user.first_name} {current_user.last_name}" return registration @router.delete("/{event_id}/register") def unregister_from_event( event_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): registration = ( db.query(EventRegistration) .filter( EventRegistration.event_id == event_id, EventRegistration.user_id == current_user.id, ) .first() ) if registration is None: raise HTTPException(status_code=404, detail="Registration not found") db.delete(registration) db.commit() return {"message": "Unregistered successfully"} @router.get("/{event_id}/registrations", response_model=List[EventRegistrationResponse]) def get_event_registrations( event_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): event = db.query(Event).filter(Event.id == event_id).first() if event is None: raise HTTPException(status_code=404, detail="Event not found") if event.created_by != current_user.id and not current_user.is_admin: raise HTTPException( status_code=403, detail="Not authorized to view registrations" ) registrations = ( db.query(EventRegistration).filter(EventRegistration.event_id == event_id).all() ) for registration in registrations: registration.user_name = ( f"{registration.user.first_name} {registration.user.last_name}" ) return registrations