package handlers import ( "log" "net/http" "strconv" "github.com/patel-mann/poll-system/app/internal/models" "github.com/patel-mann/poll-system/app/internal/utils" ) // PaginationInfo holds pagination metadata type PaginationInfo struct { CurrentPage int TotalPages int TotalRecords int PageSize int HasPrevious bool HasNext bool StartRecord int EndRecord int PreviousPage int NextPage int FirstPage int LastPage int PageNumbers []PageNumber } type PageNumber struct { Number int IsCurrent bool } func AddressHandler(w http.ResponseWriter, r *http.Request) { // Get pagination parameters from query string pageStr := r.URL.Query().Get("page") pageSizeStr := r.URL.Query().Get("pageSize") // Default values page := 1 pageSize := 20 // Default page size // Parse page number if pageStr != "" { if p, err := strconv.Atoi(pageStr); err == nil && p > 0 { page = p } } // Parse page size if pageSizeStr != "" { if ps, err := strconv.Atoi(pageSizeStr); err == nil && ps > 0 && ps <= 100 { pageSize = ps } } // Calculate offset offset := (page - 1) * pageSize // Get total count first var totalRecords int err := models.DB.QueryRow(`SELECT COUNT(*) FROM "address_database"`).Scan(&totalRecords) if err != nil { log.Println("Count query error:", err) http.Error(w, "Database error", http.StatusInternalServerError) return } // Calculate pagination info totalPages := (totalRecords + pageSize - 1) / pageSize if totalPages == 0 { totalPages = 1 } // Ensure current page is within bounds if page > totalPages { page = totalPages offset = (page - 1) * pageSize } // Get paginated results rows, err := models.DB.Query(` SELECT address_id, address, street_name, street_type, street_quadrant, house_number, house_alpha, longitude, latitude, visited_validated FROM "address_database" WHERE street_quadrant = 'ne' ORDER BY address_id LIMIT $1 OFFSET $2 `, pageSize, offset) if err != nil { log.Println("Query error:", err) http.Error(w, "Database error", http.StatusInternalServerError) return } defer rows.Close() var addresses []models.AddressDatabase for rows.Next() { var a models.AddressDatabase err := rows.Scan( &a.AddressID, &a.Address, &a.StreetName, &a.StreetType, &a.StreetQuadrant, &a.HouseNumber, &a.HouseAlpha, &a.Longitude, &a.Latitude, &a.VisitedValidated, ) if err != nil { log.Println("Scan error:", err) continue } addresses = append(addresses, a) } // Calculate start and end record numbers for display startRecord := offset + 1 endRecord := offset + len(addresses) if totalRecords == 0 { startRecord = 0 } // Generate page numbers for pagination controls pageNumbers := generatePageNumbers(page, totalPages) pagination := PaginationInfo{ CurrentPage: page, TotalPages: totalPages, TotalRecords: totalRecords, PageSize: pageSize, HasPrevious: page > 1, HasNext: page < totalPages, StartRecord: startRecord, EndRecord: endRecord, PreviousPage: page - 1, NextPage: page + 1, FirstPage: 1, LastPage: totalPages, PageNumbers: pageNumbers, } utils.Render(w, "address/address.html", map[string]interface{}{ "Title": "Addresses", "IsAuthenticated": true, "ShowAdminNav": true, "ActiveSection": "address", // Add this line "Addresses": addresses, "Role": "admin", "Pagination": pagination, }) } func generatePageNumbers(currentPage, totalPages int) []PageNumber { var pageNumbers []PageNumber // Generate page numbers to show (max 7 pages) start := currentPage - 3 end := currentPage + 3 if start < 1 { end += 1 - start start = 1 } if end > totalPages { start -= end - totalPages end = totalPages } if start < 1 { start = 1 } for i := start; i <= end; i++ { pageNumbers = append(pageNumbers, PageNumber{ Number: i, IsCurrent: i == currentPage, }) } return pageNumbers }