繰り返し課題のAPI管理UIを追加、課題一覧のUX向上
This commit is contained in:
167
internal/handler/api_recurring_handler.go
Normal file
167
internal/handler/api_recurring_handler.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"homework-manager/internal/middleware"
|
||||
"homework-manager/internal/models"
|
||||
"homework-manager/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type APIRecurringHandler struct {
|
||||
recurringService *service.RecurringAssignmentService
|
||||
}
|
||||
|
||||
func NewAPIRecurringHandler() *APIRecurringHandler {
|
||||
return &APIRecurringHandler{
|
||||
recurringService: service.NewRecurringAssignmentService(),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *APIRecurringHandler) getUserID(c *gin.Context) uint {
|
||||
userID, _ := c.Get(middleware.UserIDKey)
|
||||
return userID.(uint)
|
||||
}
|
||||
|
||||
func (h *APIRecurringHandler) ListRecurring(c *gin.Context) {
|
||||
userID := h.getUserID(c)
|
||||
|
||||
recurringList, err := h.recurringService.GetAllByUser(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch recurring assignments"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"recurring_assignments": recurringList,
|
||||
"count": len(recurringList),
|
||||
})
|
||||
}
|
||||
|
||||
func (h *APIRecurringHandler) GetRecurring(c *gin.Context) {
|
||||
userID := h.getUserID(c)
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
recurring, err := h.recurringService.GetByID(userID, uint(id))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Recurring assignment not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, recurring)
|
||||
}
|
||||
|
||||
type UpdateRecurringAPIInput struct {
|
||||
Title *string `json:"title"`
|
||||
Description *string `json:"description"`
|
||||
Subject *string `json:"subject"`
|
||||
Priority *string `json:"priority"`
|
||||
RecurrenceType *string `json:"recurrence_type"`
|
||||
RecurrenceInterval *int `json:"recurrence_interval"`
|
||||
RecurrenceWeekday *int `json:"recurrence_weekday"`
|
||||
RecurrenceDay *int `json:"recurrence_day"`
|
||||
DueTime *string `json:"due_time"`
|
||||
EndType *string `json:"end_type"`
|
||||
EndCount *int `json:"end_count"`
|
||||
EndDate *string `json:"end_date"` // YYYY-MM-DD
|
||||
IsActive *bool `json:"is_active"` // To stop/resume
|
||||
ReminderEnabled *bool `json:"reminder_enabled"`
|
||||
ReminderOffset *int `json:"reminder_offset"`
|
||||
UrgentReminderEnabled *bool `json:"urgent_reminder_enabled"`
|
||||
EditBehavior string `json:"edit_behavior"` // this_only, this_and_future, all (default: this_only)
|
||||
}
|
||||
|
||||
func (h *APIRecurringHandler) UpdateRecurring(c *gin.Context) {
|
||||
userID := h.getUserID(c)
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var input UpdateRecurringAPIInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
existing, err := h.recurringService.GetByID(userID, uint(id))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Recurring assignment not found"})
|
||||
return
|
||||
}
|
||||
|
||||
if input.IsActive != nil {
|
||||
if err := h.recurringService.SetActive(userID, uint(id), *input.IsActive); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update active status"})
|
||||
return
|
||||
}
|
||||
existing.IsActive = *input.IsActive
|
||||
}
|
||||
|
||||
serviceInput := service.UpdateRecurringInput{
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
Subject: input.Subject,
|
||||
Priority: input.Priority,
|
||||
RecurrenceType: input.RecurrenceType,
|
||||
RecurrenceInterval: input.RecurrenceInterval,
|
||||
RecurrenceWeekday: input.RecurrenceWeekday,
|
||||
RecurrenceDay: input.RecurrenceDay,
|
||||
DueTime: input.DueTime,
|
||||
EndType: input.EndType,
|
||||
EndCount: input.EndCount,
|
||||
EditBehavior: input.EditBehavior,
|
||||
ReminderEnabled: input.ReminderEnabled,
|
||||
ReminderOffset: input.ReminderOffset,
|
||||
UrgentReminderEnabled: input.UrgentReminderEnabled,
|
||||
}
|
||||
|
||||
if input.EndDate != nil && *input.EndDate != "" {
|
||||
endDate, err := parseDateString(*input.EndDate)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid end_date format"})
|
||||
return
|
||||
}
|
||||
serviceInput.EndDate = &endDate
|
||||
}
|
||||
|
||||
if serviceInput.EditBehavior == "" {
|
||||
serviceInput.EditBehavior = models.EditBehaviorThisOnly
|
||||
}
|
||||
|
||||
updated, err := h.recurringService.Update(userID, uint(id), serviceInput)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update recurring assignment"})
|
||||
return
|
||||
}
|
||||
|
||||
updated.IsActive = existing.IsActive
|
||||
|
||||
c.JSON(http.StatusOK, updated)
|
||||
}
|
||||
|
||||
func (h *APIRecurringHandler) DeleteRecurring(c *gin.Context) {
|
||||
userID := h.getUserID(c)
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
|
||||
return
|
||||
}
|
||||
|
||||
err = h.recurringService.Delete(userID, uint(id), false)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Recurring assignment not found or failed to delete"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Recurring assignment deleted"})
|
||||
}
|
||||
Reference in New Issue
Block a user