Files
Poll-system/app/internal/handlers/admin_addresses.go

185 lines
3.9 KiB
Go
Raw Normal View History

2025-08-26 14:13:09 -06:00
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
}