package studio import ( "enaklo-pos-be/internal/common/errors" "enaklo-pos-be/internal/entity" "enaklo-pos-be/internal/handlers/request" "enaklo-pos-be/internal/handlers/response" "enaklo-pos-be/internal/services" "encoding/json" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" ) type StudioHandler struct { service services.Studio } func (h *StudioHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route := group.Group("/studio") route.POST("/", jwt, h.Create) route.PUT("/:id", jwt, h.Update) route.GET("/:id", jwt, h.GetByID) route.GET("/search", jwt, h.Search) } func NewStudioHandler(service services.Studio) *StudioHandler { return &StudioHandler{ service: service, } } // Create handles the creation of a new studio. // @Summary Create a new studio // @Description Create a new studio based on the provided details. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param req body request.Studio true "New studio details" // @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio created successfully" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/studio [post] // @Tags Studio APIs func (h *StudioHandler) Create(c *gin.Context) { ctx := request.GetMyContext(c) var req request.Studio if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } res, err := h.service.Create(ctx, req.ToEntity()) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toStudioResponse(res), }) } // Update handles the update of an existing studio. // @Summary Update an existing studio // @Description Update the details of an existing studio based on the provided ID. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param id path int64 true "Studio ID to update" // @Param req body request.Studio true "Updated studio details" // @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio updated successfully" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/studio/{id} [put] // @Tags Studio APIs func (h *StudioHandler) Update(c *gin.Context) { ctx := request.GetMyContext(c) id := c.Param("id") studioID, err := strconv.ParseInt(id, 10, 64) if err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } var req request.Studio if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } updatedStudio, err := h.service.Update(ctx, studioID, req.ToEntity()) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toStudioResponse(updatedStudio), }) } // Search retrieves a list of studios based on search criteria. // @Summary Search for studios // @Description Search for studios based on query parameters. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param Name query string false "Studio name for search" // @Param Status query string false "Studio status for search" // @Param Limit query int false "Number of items to retrieve (default 10)" // @Param Offset query int false "Offset for pagination (default 0)" // @Success 200 {object} response.BaseResponse{data=response.StudioList} "List of studios" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/studio/search [get] // @Tags Studio APIs func (h *StudioHandler) Search(c *gin.Context) { var req request.StudioParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } studios, total, err := h.service.Search(c.Request.Context(), req.ToEntity()) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toStudioResponseList(studios, int64(total), req), }) } // GetByID retrieves details of a specific studio by ID. // @Summary Get details of a studio by ID // @Description Get details of a studio based on the provided ID. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param id path int64 true "Studio ID to retrieve" // @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio details" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/studio/{id} [get] // @Tags Studio APIs func (h *StudioHandler) GetByID(c *gin.Context) { id := c.Param("id") studioID, err := strconv.ParseInt(id, 10, 64) if err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, err := h.service.GetByID(c.Request.Context(), studioID) if err != nil { c.JSON(http.StatusInternalServerError, response.BaseResponse{ Success: false, Status: http.StatusInternalServerError, Message: err.Error(), Data: nil, }) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toStudioResponse(res), }) } func (h *StudioHandler) toStudioResponse(resp *entity.Studio) response.Studio { metadata := make(map[string]interface{}) if err := json.Unmarshal(resp.Metadata, &metadata); err != nil { //TODO taufanvps // Handle the error if the metadata cannot be unmarshaled. } return response.Studio{ ID: &resp.ID, BranchId: &resp.BranchId, Name: resp.Name, Status: string(resp.Status), Price: resp.Price, Metadata: metadata, CreatedAt: resp.CreatedAt.Format(time.RFC3339), UpdatedAt: resp.CreatedAt.Format(time.RFC3339), } } func (h *StudioHandler) toStudioResponseList(resp []*entity.Studio, total int64, req request.StudioParam) response.StudioList { var studios []response.Studio for _, b := range resp { studios = append(studios, h.toStudioResponse(b)) } return response.StudioList{ Studios: studios, Total: total, Limit: req.Limit, Offset: req.Offset, } }