package handler import ( "net/http" "strconv" "time" "lifelog/internal/service" "github.com/gin-gonic/gin" ) type Handler struct { todoSvc *service.TodoService dailyLogSvc *service.DailyLogService } func NewHandler(todoSvc *service.TodoService, dailyLogSvc *service.DailyLogService) *Handler { return &Handler{todoSvc: todoSvc, dailyLogSvc: dailyLogSvc} } // Todo handlers func (h *Handler) GetTodos(c *gin.Context) { todos, err := h.todoSvc.GetAll() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": todos}) } func (h *Handler) CreateTodo(c *gin.Context) { var req struct { Title string `json:"title" binding:"required"` Priority int `json:"priority"` DueDate string `json:"due_date"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if req.Priority == 0 { req.Priority = 2 } var dueDate *time.Time if req.DueDate != "" { t, err := time.Parse("2006-01-02", req.DueDate) if err == nil { dueDate = &t } } todo, err := h.todoSvc.Create(req.Title, req.Priority, dueDate) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"data": todo}) } func (h *Handler) UpdateTodo(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) return } var req struct { Title string `json:"title" binding:"required"` Priority int `json:"priority"` Done bool `json:"done"` DueDate string `json:"due_date"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var dueDate *time.Time if req.DueDate != "" { t, err := time.Parse("2006-01-02", req.DueDate) if err == nil { dueDate = &t } } todo, err := h.todoSvc.Update(id, req.Title, req.Priority, req.Done, dueDate) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": todo}) } func (h *Handler) ToggleTodo(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) return } todo, err := h.todoSvc.ToggleDone(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": todo}) } func (h *Handler) DeleteTodo(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) return } err = h.todoSvc.Delete(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "deleted"}) } // DailyLog handlers func (h *Handler) GetDailyLog(c *gin.Context) { date := c.Param("date") if date == "" { date = time.Now().Format("2006-01-02") } log, err := h.dailyLogSvc.GetByDate(date) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": log}) } func (h *Handler) GetRecentLogs(c *gin.Context) { limitStr := c.DefaultQuery("limit", "30") limit, _ := strconv.Atoi(limitStr) logs, err := h.dailyLogSvc.GetRecent(limit) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": logs}) } func (h *Handler) SaveDailyLog(c *gin.Context) { date := c.Param("date") if date == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "date is required"}) return } var req struct { Morning string `json:"morning"` Afternoon string `json:"afternoon"` Evening string `json:"evening"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log, err := h.dailyLogSvc.Save(date, req.Morning, req.Afternoon, req.Evening) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": log}) }