package event import ( "encoding/json" "net/http" "strconv" "time" "rideaware/internal/config" "rideaware/internal/middleware" ) type Handler struct { service *Service } func NewHandler() *Handler { return &Handler{service: NewService()} } func (h *Handler) CreateEvent(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) var req struct { Name string `json:"name"` EventDate string `json:"event_date"` EventType string `json:"event_type"` Distance float64 `json:"distance"` Priority string `json:"priority"` Location string `json:"location"` Notes string `json:"notes"` URL string `json:"url"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"}) return } eventDate, err := time.Parse("2006-01-02", req.EventDate) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid event_date format (use YYYY-MM-DD)"}) return } event, err := h.service.CreateEvent( claims.UserID, req.Name, eventDate, req.EventType, req.Priority, req.Location, req.Notes, req.URL, req.Distance, ) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(event) } func (h *Handler) GetEvents(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) events, err := h.service.GetUserEvents(claims.UserID) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch events"}) return } if events == nil { events = []Event{} } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(events) } func (h *Handler) GetUpcomingEvents(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) events, err := h.service.GetUpcomingEvents(claims.UserID, 10) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch events"}) return } if events == nil { events = []Event{} } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(events) } func (h *Handler) UpdateEvent(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) idStr := r.URL.Query().Get("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid event id"}) return } var req struct { Name string `json:"name"` EventDate string `json:"event_date"` EventType string `json:"event_type"` Distance float64 `json:"distance"` Priority string `json:"priority"` Location string `json:"location"` Notes string `json:"notes"` URL string `json:"url"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"}) return } var eventDate time.Time if req.EventDate != "" { eventDate, err = time.Parse("2006-01-02", req.EventDate) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid event_date format"}) return } } event, err := h.service.UpdateEvent( uint(id), claims.UserID, req.Name, eventDate, req.EventType, req.Priority, req.Location, req.Notes, req.URL, req.Distance, ) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(event) } func (h *Handler) DeleteEvent(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) idStr := r.URL.Query().Get("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "invalid event id"}) return } if err := h.service.DeleteEvent(uint(id), claims.UserID); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to delete event"}) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"message": "event deleted"}) } func (h *Handler) GetEventTypes(w http.ResponseWriter, r *http.Request) { types := []map[string]interface{}{ {"id": "race", "name": "Race", "icon": "\U0001F3C1", "color": "#FF1744"}, {"id": "gran_fondo", "name": "Gran Fondo", "icon": "\U0001F3C6", "color": "#FF6D00"}, {"id": "group_ride", "name": "Group Ride", "icon": "\U0001F6B4", "color": "#2979FF"}, {"id": "time_trial", "name": "Time Trial", "icon": "\u23F1\uFE0F", "color": "#AA00FF"}, {"id": "century", "name": "Century", "icon": "\U0001F5FA\uFE0F", "color": "#00C853"}, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(types) }