package handlers import ( "errors" "strconv" "time" "server/internal/middleware" "server/internal/models" "github.com/gofiber/fiber/v2" "gorm.io/gorm" "gorm.io/gorm/clause" ) // GET /classes/:rkId/seating-layout func GetClassSeatingLayoutHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { classRkID, err := strconv.ParseInt(c.Params("rkId"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid class ID"}) } var layout models.ClassSeatingLayout if err := db.Where("class_rk_id = ?", classRkID).First(&layout).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return c.JSON(fiber.Map{"layoutJson": nil}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"layoutJson": layout.LayoutJSON}) } } // PUT /classes/:rkId/seating-layout func PutClassSeatingLayoutHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { classRkID, err := strconv.ParseInt(c.Params("rkId"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid class ID"}) } var body struct { LayoutJSON string `json:"layoutJson"` } if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid body"}) } if body.LayoutJSON == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "layoutJson is required"}) } layout := models.ClassSeatingLayout{ ClassRkID: classRkID, LayoutJSON: body.LayoutJSON, UpdatedAt: time.Now(), } result := db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "class_rk_id"}}, DoUpdates: clause.AssignmentColumns([]string{"layout_json", "updated_at"}), }).Create(&layout) if result.Error != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": result.Error.Error()}) } return c.JSON(fiber.Map{"ok": true}) } } // DELETE /classes/:rkId/seating-layout func DeleteClassSeatingLayoutHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { classRkID, err := strconv.ParseInt(c.Params("rkId"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid class ID"}) } db.Where("class_rk_id = ?", classRkID).Delete(&models.ClassSeatingLayout{}) return c.JSON(fiber.Map{"ok": true}) } } // GET /staff/my-classes func GetMyClassesHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { staffID := middleware.StaffIDFromCtx(c) type classRow struct { RkID int64 `json:"rkId"` Name string `json:"name"` ClassCode string `json:"classCode"` } var rows []classRow db.Table("staff_my_classes"). Select("classes.rk_id, classes.name, classes.class_code"). Joins("JOIN classes ON classes.rk_id = staff_my_classes.class_rk_id"). Where("staff_my_classes.staff_id = ?", staffID). Scan(&rows) if rows == nil { rows = []classRow{} } return c.JSON(fiber.Map{"data": rows}) } } // POST /staff/my-classes/:classRkId func AddMyClassHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { staffID := middleware.StaffIDFromCtx(c) classRkID, err := strconv.ParseInt(c.Params("classRkId"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid class ID"}) } rec := models.StaffMyClass{StaffID: staffID, ClassRkID: classRkID} db.Clauses(clause.OnConflict{DoNothing: true}).Create(&rec) return c.JSON(fiber.Map{"ok": true}) } } // DELETE /staff/my-classes/:classRkId func RemoveMyClassHandler(db *gorm.DB) fiber.Handler { return func(c *fiber.Ctx) error { staffID := middleware.StaffIDFromCtx(c) classRkID, err := strconv.ParseInt(c.Params("classRkId"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid class ID"}) } db.Where("staff_id = ? AND class_rk_id = ?", staffID, classRkID).Delete(&models.StaffMyClass{}) return c.JSON(fiber.Map{"ok": true}) } }