File size: 4,996 Bytes
b70ff07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, or_
from typing import List, Dict, Any
from datetime import datetime, timedelta
from ..core.dependencies import get_current_active_user
from ..db.database import get_db
from ..db.models import Event, User
from ..db.schemas import EventCreate, EventUpdate, EventInDB, RecurringEventCreate

router = APIRouter()

@router.post("/events", response_model=EventInDB)
async def create_event(

    event: EventCreate,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> EventInDB:
    """Create a new calendar event"""
    db_event = Event(
        user_id=current_user.id,
        title=event.title,
        description=event.description,
        start_time=event.start_time,
        end_time=event.end_time,
        attendees=event.attendees,
        is_all_day=event.is_all_day,
        reminder_minutes=event.reminder_minutes,
        status="scheduled",
        attendee_responses={}
    )
    
    db.add(db_event)
    await db.commit()
    await db.refresh(db_event)
    return db_event

@router.get("/events", response_model=List[EventInDB])
async def get_events(

    start_date: datetime = Query(default=None),

    end_date: datetime = Query(default=None),

    include_attendee_events: bool = True,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> List[EventInDB]:
    """Get user's events within a date range"""
    if not start_date:
        start_date = datetime.now()
    if not end_date:
        end_date = start_date + timedelta(days=30)
    
    query = select(Event).where(
        Event.start_time >= start_date,
        Event.end_time <= end_date
    )
    
    if include_attendee_events:
        query = query.where(or_(
            Event.user_id == current_user.id,
            Event.attendees.contains([str(current_user.id)])
        ))
    else:
        query = query.where(Event.user_id == current_user.id)
    
    query = query.order_by(Event.start_time)
    result = await db.execute(query)
    return result.scalars().all()

@router.put("/events/{event_id}", response_model=EventInDB)
async def update_event(

    event_id: int,

    event_update: EventUpdate,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> EventInDB:
    """Update an event"""
    stmt = select(Event).where(
        Event.id == event_id,
        Event.user_id == current_user.id
    )
    result = await db.execute(stmt)
    event = result.scalar_one_or_none()
    
    if not event:
        raise HTTPException(
            status_code=404,
            detail="Event not found or you don't have permission to update it"
        )
    
    # Update event fields
    update_data = event_update.dict(exclude_unset=True)
    for field, value in update_data.items():
        setattr(event, field, value)
    
    event.updated_at = datetime.utcnow()
    await db.commit()
    await db.refresh(event)
    return event

@router.delete("/events/{event_id}")
async def delete_event(

    event_id: int,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, bool]:
    """Delete an event"""
    stmt = select(Event).where(
        Event.id == event_id,
        Event.user_id == current_user.id
    )
    result = await db.execute(stmt)
    event = result.scalar_one_or_none()
    
    if not event:
        raise HTTPException(
            status_code=404,
            detail="Event not found or you don't have permission to delete it"
        )
    
    await db.delete(event)
    await db.commit()
    return {"success": True}

@router.post("/events/{event_id}/respond")
async def respond_to_event(

    event_id: int,

    response: str,

    current_user: User = Depends(get_current_active_user),

    db: AsyncSession = Depends(get_db)

) -> Dict[str, bool]:
    """Respond to an event invitation"""
    if response not in ["accepted", "declined", "maybe"]:
        raise HTTPException(
            status_code=400,
            detail="Invalid response. Must be one of: accepted, declined, maybe"
        )
    
    stmt = select(Event).where(
        Event.id == event_id,
        Event.attendees.contains([str(current_user.id)])
    )
    result = await db.execute(stmt)
    event = result.scalar_one_or_none()
    
    if not event:
        raise HTTPException(
            status_code=404,
            detail="Event not found or you are not invited to this event"
        )
    
    # Update the response in the attendee_responses dictionary
    event.attendee_responses[str(current_user.id)] = response
    event.updated_at = datetime.utcnow()
    
    await db.commit()
    return {"success": True}