205 lines
5.2 KiB
Go
205 lines
5.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/calendarapi/internal/middleware"
|
|
"github.com/calendarapi/internal/models"
|
|
"github.com/calendarapi/internal/service"
|
|
"github.com/calendarapi/internal/utils"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type EventHandler struct {
|
|
eventSvc *service.EventService
|
|
}
|
|
|
|
func NewEventHandler(eventSvc *service.EventService) *EventHandler {
|
|
return &EventHandler{eventSvc: eventSvc}
|
|
}
|
|
|
|
func (h *EventHandler) List(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := middleware.GetUserID(r.Context())
|
|
q := r.URL.Query()
|
|
|
|
startStr := q.Get("start")
|
|
endStr := q.Get("end")
|
|
if startStr == "" || endStr == "" {
|
|
utils.WriteError(w, models.NewValidationError("start and end query params required"))
|
|
return
|
|
}
|
|
start, err := time.Parse(time.RFC3339, startStr)
|
|
if err != nil {
|
|
utils.WriteError(w, models.NewValidationError("invalid start time"))
|
|
return
|
|
}
|
|
end, err := time.Parse(time.RFC3339, endStr)
|
|
if err != nil {
|
|
utils.WriteError(w, models.NewValidationError("invalid end time"))
|
|
return
|
|
}
|
|
|
|
var calendarID *uuid.UUID
|
|
if cid := q.Get("calendar_id"); cid != "" {
|
|
id, err := utils.ValidateUUID(cid)
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
calendarID = &id
|
|
}
|
|
|
|
var search *string
|
|
if s := q.Get("search"); s != "" {
|
|
search = &s
|
|
}
|
|
var tag *string
|
|
if t := q.Get("tag"); t != "" {
|
|
tag = &t
|
|
}
|
|
|
|
limit := 50
|
|
if l := q.Get("limit"); l != "" {
|
|
if v, err := strconv.Atoi(l); err == nil {
|
|
limit = v
|
|
}
|
|
}
|
|
|
|
events, cursor, err := h.eventSvc.List(r.Context(), userID, service.ListEventParams{
|
|
RangeStart: start,
|
|
RangeEnd: end,
|
|
CalendarID: calendarID,
|
|
Search: search,
|
|
Tag: tag,
|
|
Limit: limit,
|
|
Cursor: q.Get("cursor"),
|
|
})
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
utils.WriteList(w, events, models.PageInfo{Limit: int(utils.ClampLimit(limit)), NextCursor: cursor})
|
|
}
|
|
|
|
func (h *EventHandler) Create(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := middleware.GetUserID(r.Context())
|
|
|
|
var req struct {
|
|
CalendarID uuid.UUID `json:"calendar_id"`
|
|
Title string `json:"title"`
|
|
Description *string `json:"description"`
|
|
Location *string `json:"location"`
|
|
StartTime time.Time `json:"start_time"`
|
|
EndTime time.Time `json:"end_time"`
|
|
Timezone string `json:"timezone"`
|
|
AllDay bool `json:"all_day"`
|
|
RecurrenceRule *string `json:"recurrence_rule"`
|
|
Reminders []int32 `json:"reminders"`
|
|
Tags []string `json:"tags"`
|
|
}
|
|
if err := utils.DecodeJSON(r, &req); err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
event, err := h.eventSvc.Create(r.Context(), userID, service.CreateEventRequest{
|
|
CalendarID: req.CalendarID,
|
|
Title: req.Title,
|
|
Description: req.Description,
|
|
Location: req.Location,
|
|
StartTime: req.StartTime,
|
|
EndTime: req.EndTime,
|
|
Timezone: req.Timezone,
|
|
AllDay: req.AllDay,
|
|
RecurrenceRule: req.RecurrenceRule,
|
|
Reminders: req.Reminders,
|
|
Tags: req.Tags,
|
|
})
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
utils.WriteJSON(w, http.StatusOK, map[string]interface{}{"event": event})
|
|
}
|
|
|
|
func (h *EventHandler) Get(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := middleware.GetUserID(r.Context())
|
|
eventID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
event, err := h.eventSvc.Get(r.Context(), userID, eventID)
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
utils.WriteJSON(w, http.StatusOK, map[string]interface{}{"event": event})
|
|
}
|
|
|
|
func (h *EventHandler) Update(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := middleware.GetUserID(r.Context())
|
|
eventID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Title *string `json:"title"`
|
|
Description *string `json:"description"`
|
|
Location *string `json:"location"`
|
|
StartTime *time.Time `json:"start_time"`
|
|
EndTime *time.Time `json:"end_time"`
|
|
Timezone *string `json:"timezone"`
|
|
AllDay *bool `json:"all_day"`
|
|
RecurrenceRule *string `json:"recurrence_rule"`
|
|
Tags []string `json:"tags"`
|
|
}
|
|
if err := utils.DecodeJSON(r, &req); err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
event, err := h.eventSvc.Update(r.Context(), userID, eventID, service.UpdateEventRequest{
|
|
Title: req.Title,
|
|
Description: req.Description,
|
|
Location: req.Location,
|
|
StartTime: req.StartTime,
|
|
EndTime: req.EndTime,
|
|
Timezone: req.Timezone,
|
|
AllDay: req.AllDay,
|
|
RecurrenceRule: req.RecurrenceRule,
|
|
Tags: req.Tags,
|
|
})
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
utils.WriteJSON(w, http.StatusOK, map[string]interface{}{"event": event})
|
|
}
|
|
|
|
func (h *EventHandler) Delete(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := middleware.GetUserID(r.Context())
|
|
eventID, err := utils.ValidateUUID(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
if err := h.eventSvc.Delete(r.Context(), userID, eventID); err != nil {
|
|
utils.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
utils.WriteOK(w)
|
|
}
|