devices-details: added pagination component
Some checks failed
/ push (push) Has been cancelled

This commit is contained in:
Tigor Hutasuhut 2024-05-12 18:13:00 +07:00
parent 06cd155f72
commit 3f3bc72f30
4 changed files with 73 additions and 4 deletions

View file

@ -0,0 +1,31 @@
package components
import "github.com/tigorlazuardi/redmage/views"
import "strconv"
import "github.com/tigorlazuardi/redmage/views/utils"
import "strings"
type PaginationData struct {
Offset int64
Limit int64
BaseURL string
Total int64
Classes []string
}
templ Pagination(c *views.Context, data PaginationData) {
if data.Total > data.Limit {
<div class="join">
for i, count := 1, int64(0); count < data.Total; i, count = i+1, count+data.Limit {
<a
href={ c.URLWithExtraQuery(data.BaseURL, "offset", strconv.FormatInt(count, 10)) }
class={ utils.CXX(
"join-item btn no-underline", true,
"btn-active", data.Offset <= count && data.Offset > count - data.Limit ,
strings.Join(data.Classes, " "), len(data.Classes) > 0,
) }
>{ strconv.Itoa(i) }</a>
}
</div>
}
}

View file

@ -1,9 +1,11 @@
package views package views
import ( import (
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"github.com/a-h/templ"
"github.com/tigorlazuardi/redmage/config" "github.com/tigorlazuardi/redmage/config"
) )
@ -21,6 +23,18 @@ func (c *Context) AppendQuery(keyValue ...string) string {
return query.Encode() return query.Encode()
} }
// URLWithExtraQuery creates a query based from baseUrl with queries joined between
// current context and extraQueries.
//
// extraKeyValues is an alternating key-value pair.
func (c *Context) URLWithExtraQuery(baseUrl string, extraKeyValues ...string) templ.SafeURL {
query := c.Request.URL.Query()
for i := 0; i < len(extraKeyValues); i += 2 {
query.Set(extraKeyValues[i], extraKeyValues[i+1])
}
return templ.SafeURL(fmt.Sprintf("%s?%s", baseUrl, query.Encode()))
}
func NewContext(config *config.Config, request *http.Request) *Context { func NewContext(config *config.Config, request *http.Request) *Context {
return &Context{ return &Context{
Config: config, Config: config,

View file

@ -42,13 +42,11 @@ templ filter(c *views.Context, data Data) {
</select> </select>
<label for="range">Range</label> <label for="range">Range</label>
<select id="range" name="created_at" class="select select-bordered w-full"> <select id="range" name="created_at" class="select select-bordered w-full">
@rangeOption(c, "", "*No Filter")
@rangeOption(c, "-10800", "3 Hours") @rangeOption(c, "-10800", "3 Hours")
@rangeOption(c, "-21600", "6 Hours") @rangeOption(c, "-21600", "6 Hours")
@rangeOption(c, "-43200", "12 Hours") @rangeOption(c, "-43200", "12 Hours")
<option @rangeOption(c, "-86400", "1 Day")
value="-86400"
selected?={ c.Request.URL.Query().Get("created_at") == "" || c.Request.URL.Query().Get("created_at") == "-86400" }
>1 Day</option>
@rangeOption(c, "-172800", "2 Days") @rangeOption(c, "-172800", "2 Days")
@rangeOption(c, "-259200", "3 Days") @rangeOption(c, "-259200", "3 Days")
@rangeOption(c, "-604800", "7 Days") @rangeOption(c, "-604800", "7 Days")

View file

@ -4,6 +4,7 @@ import "github.com/tigorlazuardi/redmage/views"
import "github.com/tigorlazuardi/redmage/views/components" import "github.com/tigorlazuardi/redmage/views/components"
import "fmt" import "fmt"
import "github.com/tigorlazuardi/redmage/models" import "github.com/tigorlazuardi/redmage/models"
import "strconv"
templ View(c *views.Context, data Data) { templ View(c *views.Context, data Data) {
@components.Doctype() { @components.Doctype() {
@ -33,10 +34,35 @@ templ Content(c *views.Context, data Data) {
</div> </div>
<div class="divider"></div> <div class="divider"></div>
@filter(c, data) @filter(c, data)
<h2>{ strconv.FormatInt(data.TotalImages, 10) } Images</h2>
if data.TotalImages > 0 {
<div class="flex justify-center mt-4">
@components.Pagination(c, components.PaginationData{
BaseURL: "/devices/details/" + data.Device.Slug,
Limit: data.Params.Limit,
Offset: data.Params.Offset,
Total: data.TotalImages,
})
</div>
<p class="text-center my-4">
Showing from
{ strconv.FormatInt(data.Params.Offset + 1, 10) }
to
{ strconv.FormatInt(min(data.Params.Limit+data.Params.Offset, data.TotalImages), 10) }
</p>
}
for _, group := range data.splitImages() { for _, group := range data.splitImages() {
<h2>{ group.Subreddit }</h2> <h2>{ group.Subreddit }</h2>
@imageList(group.Images) @imageList(group.Images)
} }
<div class="flex justify-center mt-4">
@components.Pagination(c, components.PaginationData{
BaseURL: "/devices/details/" + data.Device.Slug,
Limit: data.Params.Limit,
Offset: data.Params.Offset,
Total: data.TotalImages,
})
</div>
} }
} }
</main> </main>