Skip to content

Commit

Permalink
Merge pull request #19 from RianIhsan/feature/pagination-get-campaigns
Browse files Browse the repository at this point in the history
feature:pagination get campaigns
  • Loading branch information
RianIhsan authored Oct 29, 2023
2 parents f5c8077 + f14f0fd commit 70d7f9f
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 6 deletions.
43 changes: 43 additions & 0 deletions campaign/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ type Repository interface {
Update(campaign Campaign) (Campaign, error)
CreateImage(campaignImage CampaignImage) (CampaignImage, error)
MarkAllImagesAsNonPrimary(campaignID int) (bool, error)
GetTotalCampaigns() (int64, error)
GetPaginatedCampaigns(offset, limit int) ([]Campaign, error)
GetTotalCampaignsByUserID(userID int) (int64, error)
GetPaginatedCampaignsByUserID(userID, offset, limit int) ([]Campaign, error)
}

type repository struct {
Expand Down Expand Up @@ -90,3 +94,42 @@ func (r *repository) MarkAllImagesAsNonPrimary(campaignID int) (bool, error) {
}
return true, nil
}

func (r *repository) GetTotalCampaigns() (int64, error) {
var total int64
if err := r.db.Model(&Campaign{}).Count(&total).Error; err != nil {
return 0, err
}
return total, nil
}

func (r *repository) GetPaginatedCampaigns(offset, limit int) ([]Campaign, error) {
var campaigns []Campaign
err := r.db.Offset(offset).Limit(limit).Preload("CampaignImages", "campaign_images.is_primary = 1").Find(&campaigns).Error
if err != nil {
return campaigns, err
}

return campaigns, nil
}

func (r *repository) GetTotalCampaignsByUserID(userID int) (int64, error) {
var total int64
if err := r.db.Model(&Campaign{}).Where("user_id = ?", userID).Count(&total).Error; err != nil {
return 0, err
}
return total, nil
}

func (r *repository) GetPaginatedCampaignsByUserID(userID, offset, limit int) ([]Campaign, error) {
var campaigns []Campaign
err := r.db.Where("user_id = ?", userID).
Offset(offset).
Limit(limit).
Preload("CampaignImages", "campaign_images.is_primary = 1").
Find(&campaigns).Error
if err != nil {
return campaigns, err
}
return campaigns, nil
}
67 changes: 66 additions & 1 deletion campaign/service.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package campaign

import "errors"
import (
"errors"
"math"
)

type Service interface {
FindCampaigns(userID int) ([]Campaign, error)
FindCampaignByID(input GetCampaignDetailInput) (Campaign, error)
CreateCampaign(input CreateCampaignInput) (Campaign, error)
UpdateCampaign(inputID GetCampaignDetailInput, data CreateCampaignInput) (Campaign, error)
SaveCampaignImage(input CreateCampaignImageInput, file string) (CampaignImage, error)
GetPaginatedCampaigns(page, pageSize int) ([]Campaign, int, int, int, int, error)
GetPaginatedCampaignsByUserID(userID, page, pageSize int) ([]Campaign, int, int, int, int, error)
}

type service struct {
Expand Down Expand Up @@ -102,3 +107,63 @@ func (s *service) SaveCampaignImage(input CreateCampaignImageInput, file string)

return newCampaignImage, nil
}

func (s *service) GetPaginatedCampaigns(page, pageSize int) ([]Campaign, int, int, int, int, error) {
totalCampaigns, err := s.repository.GetTotalCampaigns()
if err != nil {
return nil, 0, 0, 0, 0, err
}

totalPages := int(math.Ceil(float64(totalCampaigns) / float64(pageSize)))
if page < 1 {
page = 1
}
if page > totalPages {
page = totalPages
}
offset := (page - 1) * pageSize
campaigns, err := s.repository.GetPaginatedCampaigns(offset, pageSize)
if err != nil {
return nil, 0, 0, 0, 0, err
}
var nextPage, prevPage int
if page < totalPages {
nextPage = page + 1
}
if page > 1 {
prevPage = page - 1
}

return campaigns, totalPages, page, nextPage, prevPage, nil
}

func (s *service) GetPaginatedCampaignsByUserID(userID, page, pageSize int) ([]Campaign, int, int, int, int, error) {
totalCampaigns, err := s.repository.GetTotalCampaignsByUserID(userID)
if err != nil {
return nil, 0, 0, 0, 0, err
}

totalPages := int(math.Ceil(float64(totalCampaigns) / float64(pageSize)))
if page < 1 {
page = 1
}
if page > totalPages {
page = totalPages
}

offset := (page - 1) * pageSize
campaigns, err := s.repository.GetPaginatedCampaignsByUserID(userID, offset, pageSize)
if err != nil {
return nil, 0, 0, 0, 0, err
}
var nextPage, prevPage int
if page < totalPages {
nextPage = page + 1
}

if page > 1 {
prevPage = page - 1
}

return campaigns, totalPages, page, nextPage, prevPage, nil
}
34 changes: 29 additions & 5 deletions handler/campaign.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,39 @@ func NewCampaignHandler(service campaign.Service) *campaignHandler {
}

func (h *campaignHandler) GetCampaigns(c *gin.Context) {
userID, _ := strconv.Atoi(c.Query("user_id"))

campaigns, err := h.service.FindCampaigns(userID)
userID, _ := strconv.Atoi(c.DefaultQuery("user_id", "0"))
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))

var campaigns []campaign.Campaign
var totalPages, currentPage, nextPage, prevPage int
var err error

if userID != 0 {
campaigns, totalPages, currentPage, nextPage, prevPage, err = h.service.GetPaginatedCampaignsByUserID(userID, page, pageSize)
} else {
campaigns, totalPages, currentPage, nextPage, prevPage, err = h.service.GetPaginatedCampaigns(page, pageSize)
}
if err != nil {
response := helper.ErrorResponse("Error to get campaigns", err)
c.JSON(http.StatusBadRequest, response)
return
}
response := helper.ResponseWithData("List of campaigns", campaign.FormatCampaigns(campaigns))

if totalPages > 1 {
if currentPage < totalPages {
nextPage = currentPage + 1
} else {
nextPage = -1
}
if currentPage > 1 {
prevPage = currentPage - 1
} else {
prevPage = -1
}
}

response := helper.ResponseWithPaginationAndNextPrev("List of campaigns", campaign.FormatCampaigns(campaigns), currentPage, totalPages, nextPage, prevPage)
c.JSON(http.StatusOK, response)

}
Expand Down Expand Up @@ -76,7 +100,7 @@ func (h *campaignHandler) CreateCampaign(c *gin.Context) {
return
}

response := helper.ErrorResponse("Success creating campaign", campaign.FormatCampaign(newCampaign))
response := helper.ResponseWithData("Success creating campaign", campaign.FormatCampaign(newCampaign))
c.JSON(http.StatusOK, response)
}

Expand Down
26 changes: 26 additions & 0 deletions helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,31 @@ func GenerateRandomOTP(otpLent int) string {
}

return string(otp)
}

type PaginationMeta struct {
CurrentPage int `json:"current_page"`
TotalPage int `json:"total_page"`
NextPage int `json:"next_page"`
PrevPage int `json:"prev_page"`
}
type TResponseWithPaginationAndNextPrev struct {
Message string `json:"message"`
Data interface{} `json:"data"`
Meta PaginationMeta `json:"meta"`
}

func ResponseWithPaginationAndNextPrev(message string, data interface{}, currentPage, totalPages, nextPage, prevPage int) TResponseWithPaginationAndNextPrev {
meta := PaginationMeta{
CurrentPage: currentPage,
TotalPage: totalPages,
NextPage: nextPage,
PrevPage: prevPage,
}

return TResponseWithPaginationAndNextPrev{
Message: message,
Data: data,
Meta: meta,
}
}

0 comments on commit 70d7f9f

Please sign in to comment.