1
0
mirror of https://github.com/jcwimer/wrestlingApp synced 2026-03-25 01:14:43 +00:00

Added pagination for the tournaments index page

This commit is contained in:
2025-09-26 12:31:37 -04:00
parent 15f85e439c
commit 3e1ae22b6b
3 changed files with 128 additions and 19 deletions

View File

@@ -221,12 +221,26 @@ class TournamentsController < ApplicationController
end
def index
if params[:search]
# @tournaments = Tournament.limit(200).search(params[:search]).order("date DESC")
@tournaments = Tournament.limit(200).search_date_name(params[:search]).order("date DESC")
# Simple manual pagination to avoid introducing a gem.
per_page = 20
page = params[:page].to_i > 0 ? params[:page].to_i : 1
offset = (page - 1) * per_page
if params[:search].present?
tournaments = Tournament.search_date_name(params[:search]).to_a
else
@tournaments = Tournament.all.sort_by{|t| t.days_until_start}.first(20)
tournaments = Tournament.all.to_a
end
# Sort by distance from today (closest first)
today = Date.today
tournaments.sort_by! { |t| (t.date - today).abs }
@total_count = tournaments.size
@total_pages = (@total_count / per_page.to_f).ceil
@page = page
@per_page = per_page
@tournaments = tournaments.slice(offset, per_page) || []
end
def show

View File

@@ -1,28 +1,29 @@
<h1>Upcoming Tournaments</h1> <%= form_tag(tournaments_path, :method => "get", id: "search-form") do %>
<h1>Upcoming Tournaments</h1>
<%= form_tag(tournaments_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Tournaments" %>
<%= submit_tag "Search" %>
<% end %>
<p>Search by name or date YYYY-MM-DD</p>
<script>
// $(document).ready(function() {
// $('#tournamentList').dataTable();
// pagingType: "bootstrap";
// } );
</script>
<br>
<table class="table table-hover table-condensed" id="tournamentList">
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th><% if user_signed_in? %><%= link_to ' New Tournament', new_tournament_path, :class=>"fas fa-plus" %></th><% end %>
<th>
<% if user_signed_in? %>
<%= link_to ' New Tournament', new_tournament_path, :class=>"fas fa-plus" %>
<% end %>
</th>
</tr>
</thead>
<tbody>
<% @tournaments.each do |tournament| %>
<tr>
<td><%= link_to "#{tournament.name}", tournament %></td>
<td><%= link_to tournament.name, tournament %></td>
<td><%= tournament.date %></td>
<td>
<% if can? :manage, tournament %>
@@ -37,6 +38,49 @@
</tbody>
</table>
<br>
<%# Pagination controls %>
<% if @total_pages.present? && @total_pages > 1 %>
<nav aria-label="Tournaments pagination">
<ul class="pagination">
<%# Previous link %>
<% if @page > 1 %>
<li class="page-item">
<%= link_to 'Previous', tournaments_path(page: @page - 1, search: params[:search]), class: "page-link" %>
</li>
<% else %>
<li class="page-item disabled"><span class="page-link">Previous</span></li>
<% end %>
<%# Page number links (limit displayed pages for large counts) %>
<% window = 5
left = [1, @page - window/2].max
right = [@total_pages, left + window - 1].min
left = [1, right - window + 1].max
%>
<% (left..right).each do |p| %>
<% if p == @page %>
<li class="page-item active"><span class="page-link"><%= p %></span></li>
<% else %>
<li class="page-item"><%= link_to p, tournaments_path(page: p, search: params[:search]), class: "page-link" %></li>
<% end %>
<% end %>
<%# Next link %>
<% if @page < @total_pages %>
<li class="page-item">
<%= link_to 'Next', tournaments_path(page: @page + 1, search: params[:search]), class: "page-link" %>
</li>
<% else %>
<li class="page-item disabled"><span class="page-link">Next</span></li>
<% end %>
</ul>
</nav>
<p class="text-muted">
<% start_index = ((@page - 1) * @per_page) + 1
end_index = [@page * @per_page, @total_count].min
%>
Showing <%= start_index %> - <%= end_index %> of <%= @total_count %> tournaments
</p>
<% end %>

View File

@@ -1084,4 +1084,55 @@ class TournamentsControllerTest < ActionController::TestCase
assert_match(/#{match.bout_number}/, response.body, "Bout number #{match.bout_number} is missing from the bracket page")
end
end
test "index sorts tournaments by date closest to today" do
today = Date.today
t_today = Tournament.create!(name: "Closest Today", address: "123 Test St", director: "Director", director_email: "today@example.com", date: today, tournament_type: "Pool to bracket", is_public: true)
t_minus1 = Tournament.create!(name: "Minus 1", address: "123 Test St", director: "Director", director_email: "m1@example.com", date: today - 1, tournament_type: "Pool to bracket", is_public: true)
t_plus1 = Tournament.create!(name: "Plus 1", address: "123 Test St", director: "Director", director_email: "p1@example.com", date: today + 1, tournament_type: "Pool to bracket", is_public: true)
t_plus2 = Tournament.create!(name: "Plus 2", address: "123 Test St", director: "Director", director_email: "p2@example.com", date: today + 2, tournament_type: "Pool to bracket", is_public: true)
t_minus3 = Tournament.create!(name: "Minus 3", address: "123 Test St", director: "Director", director_email: "m3@example.com", date: today - 3, tournament_type: "Pool to bracket", is_public: true)
t_plus10 = Tournament.create!(name: "Plus 10", address: "123 Test St", director: "Director", director_email: "p10@example.com", date: today + 10, tournament_type: "Pool to bracket", is_public: true)
created = [t_today, t_minus1, t_plus1, t_plus2, t_minus3, t_plus10]
# Hit index
get :index
assert_response :success
# From the controller result, select only the tournaments we just created and verify their relative order
results = assigns(:tournaments).select { |t| created.map(&:id).include?(t.id) }
expected_order = created.sort_by { |t| (t.date - today).abs }.map(&:id)
# Basic ordering assertions
assert_equal expected_order, results.map(&:id), "Created tournaments should be ordered by distance from today"
assert_equal t_today.id, results.first.id, "The tournament dated today should be first (closest)"
assert_equal t_plus10.id, results.last.id, "The farthest tournament should appear last"
# Relative order checks (smaller distance should appear before larger distance)
assert results.index { |r| r.id == t_minus1.id } < results.index { |r| r.id == t_plus2.id }, "t_minus1 (distance 1) should appear before t_plus2 (distance 2)"
assert results.index { |r| r.id == t_plus2.id } < results.index { |r| r.id == t_minus3.id }, "t_plus2 (distance 2) should appear before t_minus3 (distance 3)"
end
test "index paginates tournaments with page param and exposes total_count" do
initial_count = Tournament.count
# Create 25 tournaments to ensure we exceed the per_page (20)
25.times do |i|
Tournament.create!(name: "Paginate Test #{i}", address: "1 Paginate Rd", director: "Dir", director_email: "paginate#{i}@example.com", date: Date.today + i, tournament_type: "Pool to bracket", is_public: true)
end
expected_total = initial_count + 25
# Page 1
get :index, params: { page: 1 }
assert_response :success
assert_equal expected_total, assigns(:total_count), "total_count should reflect all tournaments"
assert_equal 20, assigns(:tournaments).size, "first page should contain 20 tournaments"
# Page 2
get :index, params: { page: 2 }
assert_response :success
assert_equal expected_total, assigns(:total_count), "total_count should remain the same on subsequent pages"
expected_page2_size = expected_total - 20
# If there are more than 20 initial fixtures, expected_page2_size might be > 20; clamp to per_page logic:
expected_page2_display = [expected_page2_size, 20].min
assert_equal expected_page2_display, assigns(:tournaments).size, "second page should contain the remaining tournaments (or up to per_page)"
end
end