package discovery 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" "github.com/gin-gonic/gin" "net/http" ) type Handler struct { service services.DiscoverService } func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route := group.Group("/discovery") route.GET("/home", h.DisoveryHome) route.GET("/search", h.DisoverySearch) route.GET("/site/detail", h.DiscoveryGetByID) route.GET("/site/products", h.DiscoveryProducts) } func NewHandler(service services.DiscoverService) *Handler { return &Handler{ service: service, } } func (h *Handler) DisoveryHome(c *gin.Context) { var req request.DiscoveryHomeParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, err := h.service.Home(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: ConvertEntityToResponse(res), }) } func (h *Handler) DisoverySearch(c *gin.Context) { var req request.DiscoveryHomeParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, 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: ConvertEntityToSearchResponse(res, total, req), }) } func (h *Handler) DiscoveryGetByID(c *gin.Context) { ctx := request.GetMyContext(c) var req request.DiscoverySearchByID if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, err := h.service.GetByID(ctx, req.ID) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: ConvertEntityToGetByIDResp(res), }) } func (h *Handler) DiscoveryProducts(c *gin.Context) { ctx := request.GetMyContext(c) var req request.DiscoverySearchByID if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, err := h.service.GetProductsByID(ctx, req.ID) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: ConvertToProductResp(res), }) } func ConvertEntityToResponse(entityResp *entity.DiscoverySearchResp) *response.ExploreResponse { // Convert ExploreRegions exploreRegions := make([]response.Region, len(entityResp.ExploreRegions)) for i, region := range entityResp.ExploreRegions { exploreRegions[i] = response.Region{ Name: region.Name, } } // Convert ExploreDestinations exploreDestinations := make([]response.Destination, len(entityResp.ExploreDestinations)) for i, destination := range entityResp.ExploreDestinations { exploreDestinations[i] = response.Destination{ Name: destination.Name, ImageURL: destination.ImageURL, } } mustVisit := make([]response.MustVisit, len(entityResp.MustVisit)) for i, mv := range entityResp.MustVisit { mustVisit[i] = response.MustVisit{ Name: mv.Name, Region: mv.Region, Rating: mv.Rating, ReviewCount: mv.ReviewCount, Price: mv.Price, ImageURL: mv.ImageURL, SiteID: mv.SiteID, Regency: mv.Regency, } } return &response.ExploreResponse{ ExploreRegions: exploreRegions, ExploreDestinations: exploreDestinations, MustVisit: mustVisit, } } func ConvertEntityToSearchResponse(entityResp *entity.DiscoverySearchResp, total int64, req request.DiscoveryHomeParam) *response.SearchResponse { data := make([]response.SiteSeach, len(entityResp.MustVisit)) for i, mv := range entityResp.MustVisit { data[i] = response.SiteSeach{ Name: mv.Name, Region: mv.Region, Rating: mv.Rating, ReviewCount: mv.ReviewCount, Price: mv.Price, ImageURL: mv.ImageURL, SiteID: mv.SiteID, Regency: mv.Regency, } } return &response.SearchResponse{ Data: data, Total: int(total), Limit: req.Limit, Offset: req.Offset, } } func ConvertEntityToGetByIDResp(resp *entity.Site) *response.SearchSiteByIDResponse { if resp == nil { return nil } return &response.SearchSiteByIDResponse{ ID: resp.ID, Name: resp.Name, Image: resp.Image, Address: resp.Address, LocationLink: resp.LocationLink, Description: resp.Description, Highlight: resp.Highlight, ContactPerson: resp.ContactPerson, TnC: resp.TnC, AdditionalInfo: resp.AdditionalInfo, PartnerID: resp.PartnerID, Regency: resp.Regency, Region: resp.Region, } } func ConvertToProductResp(resp []*entity.Product) *response.SearchProductSiteResponse { if resp == nil { return nil } var productResp []response.SearchProductSiteByIDResponse partnerID := int64(0) for _, res := range resp { productResp = append(productResp, response.SearchProductSiteByIDResponse{ ID: res.ID, Name: res.Name, Price: res.Price, Description: res.Description, Type: res.Type, }) partnerID = res.PartnerID } return &response.SearchProductSiteResponse{ Product: productResp, PartnerID: partnerID, } }