Added a basic homepage

This commit is contained in:
CamZawacki 2026-05-20 16:09:54 +01:00
parent d40640a648
commit 12fd3c04ca
113 changed files with 414 additions and 506 deletions

81
internal/pager/pager.go Normal file
View file

@ -0,0 +1,81 @@
package pager
import (
"math"
"strconv"
"github.com/labstack/echo/v4"
)
// QueryKey stores the query key used to indicate the current page.
const QueryKey = "page"
// Pager provides a mechanism to allow a user to page results via a query parameter.
type Pager struct {
// Items stores the total amount of items in the result set.
Items int
// Page stores the current page number.
Page int
// ItemsPerPage stores the amount of items to display per page.
ItemsPerPage int
// Pages stores the total amount of pages in the result set.
Pages int
}
// NewPager creates a new Pager.
func NewPager(ctx echo.Context, itemsPerPage int) Pager {
p := Pager{
ItemsPerPage: itemsPerPage,
Pages: 1,
Page: 1,
}
if page := ctx.QueryParam(QueryKey); page != "" {
if pageInt, err := strconv.Atoi(page); err == nil {
if pageInt > 0 {
p.Page = pageInt
}
}
}
return p
}
// SetItems sets the amount of items in total for the pager and calculate the amount
// of total pages based off on the item per page.
// This should be used rather than setting either items or pages directly.
func (p *Pager) SetItems(items int) {
p.Items = items
if items > 0 {
p.Pages = int(math.Ceil(float64(items) / float64(p.ItemsPerPage)))
} else {
p.Pages = 1
}
if p.Page > p.Pages {
p.Page = p.Pages
}
}
// IsBeginning determines if the pager is at the beginning of the pages
func (p *Pager) IsBeginning() bool {
return p.Page == 1
}
// IsEnd determines if the pager is at the end of the pages
func (p *Pager) IsEnd() bool {
return p.Page >= p.Pages
}
// GetOffset determines the offset of the results in order to get the items for
// the current page
func (p *Pager) GetOffset() int {
if p.Page == 0 {
p.Page = 1
}
return (p.Page - 1) * p.ItemsPerPage
}

View file

@ -0,0 +1,74 @@
package pager
import (
"fmt"
"testing"
"github.com/labstack/echo/v4"
"github.com/camzawacki/personal-site/internal/tests"
"github.com/stretchr/testify/assert"
)
func TestNewPager(t *testing.T) {
e := echo.New()
ctx, _ := tests.NewContext(e, "/")
pgr := NewPager(ctx, 10)
assert.Equal(t, 10, pgr.ItemsPerPage)
assert.Equal(t, 1, pgr.Page)
assert.Equal(t, 0, pgr.Items)
assert.Equal(t, 1, pgr.Pages)
ctx, _ = tests.NewContext(e, fmt.Sprintf("/abc?%s=%d", QueryKey, 2))
pgr = NewPager(ctx, 10)
assert.Equal(t, 2, pgr.Page)
ctx, _ = tests.NewContext(e, fmt.Sprintf("/abc?%s=%d", QueryKey, -2))
pgr = NewPager(ctx, 10)
assert.Equal(t, 1, pgr.Page)
}
func TestPager_SetItems(t *testing.T) {
ctx, _ := tests.NewContext(echo.New(), "/")
pgr := NewPager(ctx, 20)
pgr.SetItems(100)
assert.Equal(t, 100, pgr.Items)
assert.Equal(t, 5, pgr.Pages)
pgr.SetItems(0)
assert.Equal(t, 0, pgr.Items)
assert.Equal(t, 1, pgr.Pages)
assert.Equal(t, 1, pgr.Page)
}
func TestPager_IsBeginning(t *testing.T) {
ctx, _ := tests.NewContext(echo.New(), "/")
pgr := NewPager(ctx, 20)
pgr.Pages = 10
assert.True(t, pgr.IsBeginning())
pgr.Page = 2
assert.False(t, pgr.IsBeginning())
pgr.Page = 1
assert.True(t, pgr.IsBeginning())
}
func TestPager_IsEnd(t *testing.T) {
ctx, _ := tests.NewContext(echo.New(), "/")
pgr := NewPager(ctx, 20)
pgr.Pages = 10
assert.False(t, pgr.IsEnd())
pgr.Page = 10
assert.True(t, pgr.IsEnd())
pgr.Page = 1
assert.False(t, pgr.IsEnd())
}
func TestPager_GetOffset(t *testing.T) {
ctx, _ := tests.NewContext(echo.New(), "/")
pgr := NewPager(ctx, 20)
assert.Equal(t, 0, pgr.GetOffset())
pgr.Page = 2
assert.Equal(t, 20, pgr.GetOffset())
pgr.Page = 3
assert.Equal(t, 40, pgr.GetOffset())
}