feat(schedule): add course table screens and navigation
Add complete schedule functionality including: - Schedule screen with weekly course table view - Course detail screen with transparent modal presentation - New ScheduleStack navigator integrated into main tab bar - Schedule service for API interactions - Type definitions for course entities Also includes bug fixes for group invite/request handlers to include required groupId parameter.
This commit is contained in:
140
internal/handler/schedule_handler.go
Normal file
140
internal/handler/schedule_handler.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"carrot_bbs/internal/pkg/response"
|
||||
"carrot_bbs/internal/service"
|
||||
)
|
||||
|
||||
type ScheduleHandler struct {
|
||||
scheduleService service.ScheduleService
|
||||
}
|
||||
|
||||
func NewScheduleHandler(scheduleService service.ScheduleService) *ScheduleHandler {
|
||||
return &ScheduleHandler{scheduleService: scheduleService}
|
||||
}
|
||||
|
||||
type createScheduleCourseRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Teacher string `json:"teacher"`
|
||||
Location string `json:"location"`
|
||||
DayOfWeek int `json:"day_of_week" binding:"required"`
|
||||
StartSection int `json:"start_section" binding:"required"`
|
||||
EndSection int `json:"end_section" binding:"required"`
|
||||
Weeks []int `json:"weeks" binding:"required,min=1"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
type updateScheduleCourseRequest = createScheduleCourseRequest
|
||||
|
||||
func (h *ScheduleHandler) ListCourses(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
|
||||
week := 0
|
||||
if rawWeek := c.Query("week"); rawWeek != "" {
|
||||
parsed, err := strconv.Atoi(rawWeek)
|
||||
if err != nil {
|
||||
response.BadRequest(c, "invalid week")
|
||||
return
|
||||
}
|
||||
week = parsed
|
||||
}
|
||||
|
||||
list, err := h.scheduleService.ListCourses(userID, week)
|
||||
if err != nil {
|
||||
response.HandleError(c, err, "failed to list schedule courses")
|
||||
return
|
||||
}
|
||||
response.Success(c, gin.H{"list": list})
|
||||
}
|
||||
|
||||
func (h *ScheduleHandler) CreateCourse(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
|
||||
var req createScheduleCourseRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
created, err := h.scheduleService.CreateCourse(userID, service.CreateScheduleCourseInput{
|
||||
Name: req.Name,
|
||||
Teacher: req.Teacher,
|
||||
Location: req.Location,
|
||||
DayOfWeek: req.DayOfWeek,
|
||||
StartSection: req.StartSection,
|
||||
EndSection: req.EndSection,
|
||||
Weeks: req.Weeks,
|
||||
Color: req.Color,
|
||||
})
|
||||
if err != nil {
|
||||
response.HandleError(c, err, "failed to create schedule course")
|
||||
return
|
||||
}
|
||||
response.SuccessWithMessage(c, "course created", gin.H{"course": created})
|
||||
}
|
||||
|
||||
func (h *ScheduleHandler) UpdateCourse(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
courseID := c.Param("id")
|
||||
if courseID == "" {
|
||||
response.BadRequest(c, "invalid course id")
|
||||
return
|
||||
}
|
||||
|
||||
var req updateScheduleCourseRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := h.scheduleService.UpdateCourse(userID, courseID, service.CreateScheduleCourseInput{
|
||||
Name: req.Name,
|
||||
Teacher: req.Teacher,
|
||||
Location: req.Location,
|
||||
DayOfWeek: req.DayOfWeek,
|
||||
StartSection: req.StartSection,
|
||||
EndSection: req.EndSection,
|
||||
Weeks: req.Weeks,
|
||||
Color: req.Color,
|
||||
})
|
||||
if err != nil {
|
||||
response.HandleError(c, err, "failed to update schedule course")
|
||||
return
|
||||
}
|
||||
response.SuccessWithMessage(c, "course updated", gin.H{"course": updated})
|
||||
}
|
||||
|
||||
func (h *ScheduleHandler) DeleteCourse(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
response.Unauthorized(c, "")
|
||||
return
|
||||
}
|
||||
courseID := c.Param("id")
|
||||
if courseID == "" {
|
||||
response.BadRequest(c, "invalid course id")
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.scheduleService.DeleteCourse(userID, courseID); err != nil {
|
||||
response.HandleError(c, err, "failed to delete schedule course")
|
||||
return
|
||||
}
|
||||
response.SuccessWithMessage(c, "course deleted", nil)
|
||||
}
|
||||
Reference in New Issue
Block a user