mirror of
				https://github.com/yanislav-igonin/micrach
				synced 2025-11-03 02:27:02 +03:00 
			
		
		
		
	feat: add pagination
This commit is contained in:
		
							parent
							
								
									8860c4f26c
								
							
						
					
					
						commit
						9b69eb46b7
					
				@ -2,6 +2,7 @@ package controlers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -11,13 +12,34 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetThreads(c *gin.Context) {
 | 
					func GetThreads(c *gin.Context) {
 | 
				
			||||||
	threads, err := Repositories.Posts.Get(10, 10)
 | 
						pageString := c.Query("page")
 | 
				
			||||||
 | 
						page, err := strconv.Atoi(pageString)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("error:", err)
 | 
							log.Println("error:", err)
 | 
				
			||||||
		c.HTML(http.StatusOK, "500.html", nil)
 | 
							c.HTML(http.StatusOK, "500.html", nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.HTML(http.StatusOK, "index.html", threads)
 | 
						limit := 10
 | 
				
			||||||
 | 
						offset := limit * (page - 1)
 | 
				
			||||||
 | 
						threads, err := Repositories.Posts.Get(limit, offset)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println("error:", err)
 | 
				
			||||||
 | 
							c.HTML(http.StatusOK, "500.html", nil)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						count, err := Repositories.Posts.GetCount()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println("error:", err)
 | 
				
			||||||
 | 
							c.HTML(http.StatusOK, "500.html", nil)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data := Repositories.IndexPageData{
 | 
				
			||||||
 | 
							Threads:    threads,
 | 
				
			||||||
 | 
							PagesCount: int(math.Ceil(float64(count) / 10)),
 | 
				
			||||||
 | 
							Page:       page,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.HTML(http.StatusOK, "index.html", data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetThread(c *gin.Context) {
 | 
					func GetThread(c *gin.Context) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								main.go
									
									
									
									
									
								
							@ -1,6 +1,7 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"html/template"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@ -41,6 +42,16 @@ func main() {
 | 
				
			|||||||
	middleware := mgin.NewMiddleware(instance)
 | 
						middleware := mgin.NewMiddleware(instance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	router := gin.Default()
 | 
						router := gin.Default()
 | 
				
			||||||
 | 
						router.SetFuncMap(template.FuncMap{
 | 
				
			||||||
 | 
							"Iterate": func(count int) []int {
 | 
				
			||||||
 | 
								var i int
 | 
				
			||||||
 | 
								var Items []int
 | 
				
			||||||
 | 
								for i = 1; i < count; i++ {
 | 
				
			||||||
 | 
									Items = append(Items, i)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return Items
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	router.LoadHTMLGlob("templates/*.html")
 | 
						router.LoadHTMLGlob("templates/*.html")
 | 
				
			||||||
	router.ForwardedByClientIP = true
 | 
						router.ForwardedByClientIP = true
 | 
				
			||||||
	if Config.App.IsRateLimiterEnabled {
 | 
						if Config.App.IsRateLimiterEnabled {
 | 
				
			||||||
 | 
				
			|||||||
@ -19,10 +19,11 @@ func (r *PostsRepository) Get(limit, offset int) ([]Post, error) {
 | 
				
			|||||||
			is_parent = true
 | 
								is_parent = true
 | 
				
			||||||
			AND is_deleted = false
 | 
								AND is_deleted = false
 | 
				
			||||||
		ORDER BY updated_at DESC
 | 
							ORDER BY updated_at DESC
 | 
				
			||||||
		LIMIT $1
 | 
							OFFSET $1
 | 
				
			||||||
 | 
							LIMIT $2
 | 
				
			||||||
	`
 | 
						`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rows, err := Db.Pool.Query(context.TODO(), sql, limit)
 | 
						rows, err := Db.Pool.Query(context.TODO(), sql, offset, limit)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -58,6 +59,24 @@ func (r *PostsRepository) Get(limit, offset int) ([]Post, error) {
 | 
				
			|||||||
	return posts, nil
 | 
						return posts, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *PostsRepository) GetCount() (int, error) {
 | 
				
			||||||
 | 
						sql := `
 | 
				
			||||||
 | 
							SELECT COUNT(*)
 | 
				
			||||||
 | 
							FROM posts
 | 
				
			||||||
 | 
							WHERE 
 | 
				
			||||||
 | 
								is_parent = true
 | 
				
			||||||
 | 
								AND is_deleted = false
 | 
				
			||||||
 | 
						`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						row := Db.Pool.QueryRow(context.TODO(), sql)
 | 
				
			||||||
 | 
						var count int
 | 
				
			||||||
 | 
						err := row.Scan(&count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return count, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *PostsRepository) Create(p Post) (int, error) {
 | 
					func (r *PostsRepository) Create(p Post) (int, error) {
 | 
				
			||||||
	sql := `
 | 
						sql := `
 | 
				
			||||||
		INSERT INTO posts (is_parent, parent_id, title, text, is_sage)
 | 
							INSERT INTO posts (is_parent, parent_id, title, text, is_sage)
 | 
				
			||||||
 | 
				
			|||||||
@ -23,3 +23,9 @@ type File struct {
 | 
				
			|||||||
	Ext       string    `json:"-"`
 | 
						Ext       string    `json:"-"`
 | 
				
			||||||
	Size      int       `json:"size"`
 | 
						Size      int       `json:"size"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IndexPageData struct {
 | 
				
			||||||
 | 
						Threads    []Post
 | 
				
			||||||
 | 
						PagesCount int
 | 
				
			||||||
 | 
						Page       int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					#pagesList {
 | 
				
			||||||
 | 
					  flex-wrap: wrap
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -15,19 +15,19 @@
 | 
				
			|||||||
  <div class="container">
 | 
					  <div class="container">
 | 
				
			||||||
    {{ template "post-form" }}
 | 
					    {{ template "post-form" }}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    <div class="row row-cols-auto gy-4">
 | 
					    <div id="" class="row row-cols-auto gy-4 mb-4">
 | 
				
			||||||
      {{range $Post := .}}
 | 
					      {{ range $Post := .Threads }}
 | 
				
			||||||
      <div class="col col-sm-6 col-md-4 col-lg-3">
 | 
					      <div class="col col-sm-6 col-md-4 col-lg-3">
 | 
				
			||||||
        <div class="card">
 | 
					        <div class="card">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          {{ $length := len $Post.Files }} {{ if gt $length 0 }}
 | 
					          {{ $length := len $Post.Files }} {{ if gt $length 0 }}
 | 
				
			||||||
          {{$FirstFile := index $Post.Files 0}}
 | 
					          {{ $FirstFile := index $Post.Files 0 }}
 | 
				
			||||||
          <img 
 | 
					          <img 
 | 
				
			||||||
            src="{{$FirstFile.Name}}" 
 | 
					            src="{{$FirstFile.Name}}" 
 | 
				
			||||||
            class="card-img-top"
 | 
					            class="card-img-top"
 | 
				
			||||||
            alt="Uploaded picture"
 | 
					            alt="Uploaded picture"
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
          {{end}}
 | 
					          {{ end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div class="card-body">
 | 
					          <div class="card-body">
 | 
				
			||||||
            <h5 class="card-title">{{$Post.Title}}</h5>
 | 
					            <h5 class="card-title">{{$Post.Title}}</h5>
 | 
				
			||||||
@ -36,7 +36,20 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      {{end}}
 | 
					      {{ end }}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="col col-12">
 | 
				
			||||||
 | 
					      <nav aria-label="Page navigation">
 | 
				
			||||||
 | 
					        <ul id="pagesList" class="pagination justify-content-center">
 | 
				
			||||||
 | 
					          {{ $ActivePage := .Page }}
 | 
				
			||||||
 | 
					          {{ range $i := Iterate .PagesCount }}
 | 
				
			||||||
 | 
					            <li class="page-item {{ if (eq $i $ActivePage) }} active {{ end }}">
 | 
				
			||||||
 | 
					              <a class="page-link" href="/?page={{ $i }}">{{ $i }}</a>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					          {{ end }}
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					      </nav>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user