package controllers import ( "fmt" "strconv" "abdanhafidz.com/go-boilerplate/models/dto" "abdanhafidz.com/go-boilerplate/services" "github.com/gin-gonic/gin" ) type VenueController interface { GetAllVenues(ctx *gin.Context) GetOwnerVenues(ctx *gin.Context) GetVenueDetail(ctx *gin.Context) CreateVenue(ctx *gin.Context) UpdateVenue(ctx *gin.Context) DeleteVenue(ctx *gin.Context) } type venueController struct { venueService services.VenueService } func NewVenueController(venueService services.VenueService) VenueController { return &venueController{venueService: venueService} } // GetAllVenues godoc // @Summary Get all venues // @Description Returns a paginated list of all venues. // @Tags Venue // @Produce json // @Param page query int false "Page number (default: 1)" // @Param limit query int false "Items per page (default: 10, max: 50)" // @Success 200 {object} dto.VenueListResponse // @Failure 500 {object} dto.ErrorResponse // @Router /api/v1/venues [get] func (c *venueController) GetAllVenues(ctx *gin.Context) { page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) result, err := c.venueService.GetAllVenues(ctx.Request.Context(), page, limit) if err != nil { ResponseJSON(ctx, "", result, err) return } ResponseJSON(ctx, "", result, nil) } // GetOwnerVenues godoc // @Summary Get owner's venues // @Description Returns a paginated list of venues owned by the current user. // @Tags Venue // @Produce json // @Param page query int false "Page number (default: 1)" // @Param limit query int false "Items per page (default: 10, max: 50)" // @Success 200 {object} dto.VenueListResponse // @Failure 401 {object} dto.ErrorResponse // @Security BearerAuth // @Router /api/v1/venues/me [get] func (c *venueController) GetOwnerVenues(ctx *gin.Context) { userID := ParseUserId(ctx) if userID == "" { return } page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) result, err := c.venueService.GetOwnerVenues(ctx.Request.Context(), userID, page, limit) if err != nil { ResponseJSON(ctx, "", result, err) return } ResponseJSON(ctx, "", result, nil) } // GetVenueDetail godoc // @Summary Get venue detail // @Description Returns the full detail of a venue by its ID. // @Tags Venue // @Produce json // @Param id path string true "Venue ID" // @Success 200 {object} dto.VenueDetailResponse // @Failure 404 {object} dto.ErrorResponse // @Security BearerAuth // @Router /api/v1/venues/{id} [get] func (c *venueController) GetVenueDetail(ctx *gin.Context) { venueID := ctx.Param("id") if venueID == "" { ResponseJSON(ctx, "", dto.VenueDetailResponse{}, nil) return } venue, err := c.venueService.GetVenueDetail(ctx.Request.Context(), venueID) if err != nil { ResponseJSON(ctx, "", venue, err) return } ResponseJSON(ctx, "", venue, nil) } // CreateVenue godoc // @Summary Create a new venue // @Description Submit the Add Venue form with detailed location, facilities, specs, and photos URLs. // @Tags Venue // @Accept json // @Produce json // @Param request body dto.CreateVenueRequest true "Create Venue Form Data" // @Success 200 {object} dto.VenueResponse // @Failure 400 {object} dto.ErrorResponse // @Security BearerAuth // @Router /api/v1/venues [post] func (c *venueController) CreateVenue(ctx *gin.Context) { userID := ParseUserId(ctx) if userID == "" { return // Handled by ParseUserId } req, err := RequestJSON[dto.CreateVenueRequest](ctx) if err != nil { return } res, err := c.venueService.CreateVenue(ctx.Request.Context(), userID, req) if err != nil { ResponseJSON(ctx, "", res, err) return } ResponseJSON(ctx, "", res, nil) } // UpdateVenue godoc // @Summary Update an existing venue // @Description Update the details of an existing venue owned by the current user. // @Tags Venue // @Accept json // @Produce json // @Param id path string true "Venue ID" // @Param request body dto.UpdateVenueRequest true "Update Venue Form Data" // @Success 200 {object} dto.VenueDetailResponse // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Failure 404 {object} dto.ErrorResponse // @Security BearerAuth // @Router /api/v1/venues/{id} [put] func (c *venueController) UpdateVenue(ctx *gin.Context) { userID := ParseUserId(ctx) if userID == "" { return } venueID := ctx.Param("id") if venueID == "" { ResponseJSON(ctx, "", dto.VenueDetailResponse{}, fmt.Errorf("venue id is required")) return } req, err := RequestJSON[dto.UpdateVenueRequest](ctx) if err != nil { return } res, err := c.venueService.UpdateVenue(ctx.Request.Context(), userID, venueID, req) if err != nil { ResponseJSON(ctx, "", dto.VenueDetailResponse{}, err) return } ResponseJSON(ctx, "", res, nil) } // DeleteVenue godoc // @Summary Delete a venue // @Description Delete an existing venue owned by the current user if it has no classes attached. // @Tags Venue // @Produce json // @Param id path string true "Venue ID" // @Success 200 {object} map[string]interface{} // @Failure 400 {object} dto.ErrorResponse // @Failure 401 {object} dto.ErrorResponse // @Failure 403 {object} dto.ErrorResponse // @Failure 404 {object} dto.ErrorResponse // @Security BearerAuth // @Router /api/v1/venues/{id} [delete] func (c *venueController) DeleteVenue(ctx *gin.Context) { userID := ParseUserId(ctx) if userID == "" { return } venueID := ctx.Param("id") if venueID == "" { ResponseJSON(ctx, "", map[string]interface{}{}, fmt.Errorf("venue id is required")) return } err := c.venueService.DeleteVenue(ctx.Request.Context(), userID, venueID) if err != nil { ResponseJSON(ctx, "", map[string]interface{}{}, err) return } ResponseJSON(ctx, "Venue deleted successfully", map[string]interface{}{}, nil) }