now with pagination

This commit is contained in:
Gavin McDonald
2025-12-16 18:27:39 -05:00
parent 4a7e966744
commit e78ec9fee4
5 changed files with 122 additions and 8 deletions

View File

@@ -71,6 +71,8 @@ defmodule LabelmakerWeb.Constants do
"verdana" => "Verdana" "verdana" => "Verdana"
} }
@labels_per_page 4
@max_height 1024 @max_height 1024
@max_width 1024 @max_width 1024
@@ -99,6 +101,7 @@ defmodule LabelmakerWeb.Constants do
|> Enum.map(fn color -> color |> String.replace("-MS", "") |> String.replace("-", " ") end) |> Enum.map(fn color -> color |> String.replace("-MS", "") |> String.replace("-", " ") end)
def font_map, do: @font_map def font_map, do: @font_map
def labels_per_page, do: @labels_per_page
def max_height, do: @max_height def max_height, do: @max_height
def max_width, do: @max_width def max_width, do: @max_width
def max_label_length, do: @max_label_length def max_label_length, do: @max_label_length

View File

@@ -1,11 +1,42 @@
defmodule LabelmakerWeb.LabelsController do defmodule LabelmakerWeb.LabelsController do
use LabelmakerWeb, :controller use LabelmakerWeb, :controller
alias LabelmakerWeb.Constants
@label_dir Path.join(:code.priv_dir(:labelmaker), "static/labels") @label_dir Path.join(:code.priv_dir(:labelmaker), "static/labels")
def index(conn, _params) do def index(conn, params) do
labels = list_labels() page = parse_page(params["page"])
render(conn, :index, labels: labels) all_labels = list_labels()
total_count = length(all_labels)
total_pages = ceil(total_count / Constants.labels_per_page())
# Ensure page is within valid range
page = max(1, min(page, max(total_pages, 1)))
labels = paginate(all_labels, page)
render(conn, :index,
labels: labels,
page: page,
total_pages: total_pages,
total_count: total_count,
per_page: Constants.labels_per_page()
)
end
defp parse_page(nil), do: 1
defp parse_page(page_str) do
case Integer.parse(page_str) do
{page, _} when page > 0 -> page
_ -> 1
end
end
defp paginate(labels, page) do
labels
|> Enum.drop((page - 1) * Constants.labels_per_page())
|> Enum.take(Constants.labels_per_page())
end end
defp list_labels do defp list_labels do

View File

@@ -13,4 +13,24 @@ defmodule LabelmakerWeb.LabelsHTML do
defp pad(num) when num < 10, do: "0#{num}" defp pad(num) when num < 10, do: "0#{num}"
defp pad(num), do: "#{num}" defp pad(num), do: "#{num}"
def pagination_range(current_page, total_pages) do
cond do
total_pages <= 7 ->
# Show all pages if there are 7 or fewer
1..total_pages
current_page <= 4 ->
# Near the beginning: show first 5, then last
[1, 2, 3, 4, 5, :ellipsis, total_pages]
current_page >= total_pages - 3 ->
# Near the end: show first, then last 5
[1, :ellipsis, total_pages - 4, total_pages - 3, total_pages - 2, total_pages - 1, total_pages]
true ->
# In the middle: show first, current +/- 1, and last
[1, :ellipsis, current_page - 1, current_page, current_page + 1, :ellipsis, total_pages]
end
end
end end

View File

@@ -4,7 +4,7 @@
<a href={~p"/"} class="text-primary hover:underline">← Back to Home</a> <a href={~p"/"} class="text-primary hover:underline">← Back to Home</a>
</div> </div>
<%= if Enum.empty?(@labels) do %> <%= if @total_count == 0 do %>
<div class="text-center py-12"> <div class="text-center py-12">
<p class="text-xl text-gray-600 dark:text-gray-400 mb-4"> <p class="text-xl text-gray-600 dark:text-gray-400 mb-4">
No labels generated yet. No labels generated yet.
@@ -17,8 +17,15 @@
</a> </a>
</div> </div>
<% else %> <% else %>
<div class="mb-4 text-gray-600 dark:text-gray-400"> <div class="mb-4 flex justify-between items-center">
Total labels: <%= length(@labels) %> <div class="text-gray-600 dark:text-gray-400">
Showing <%= (@page - 1) * @per_page + 1 %>-<%= min(@page * @per_page, @total_count) %> of <%= @total_count %> labels
</div>
<%= if @total_pages > 1 do %>
<div class="text-sm text-gray-600 dark:text-gray-400">
Page <%= @page %> of <%= @total_pages %>
</div>
<% end %>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
@@ -70,5 +77,58 @@
</div> </div>
<% end %> <% end %>
</div> </div>
<%= if @total_pages > 1 do %>
<div class="mt-8 flex justify-center items-center gap-2">
<%= if @page > 1 do %>
<a
href={~p"/labels?page=#{@page - 1}"}
class="px-4 py-2 bg-secondary-light dark:bg-secondary-dark border border-gray-300 dark:border-gray-600 rounded text-fg-light dark:text-fg-dark hover:bg-primary hover:text-white transition"
>
← Previous
</a>
<% else %>
<span class="px-4 py-2 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded text-gray-400 dark:text-gray-600 cursor-not-allowed">
← Previous
</span>
<% end %>
<div class="flex gap-1">
<%= for page_num <- pagination_range(@page, @total_pages) do %>
<%= if page_num == :ellipsis do %>
<span class="px-3 py-2 text-gray-400 dark:text-gray-600">
...
</span>
<% else %>
<%= if page_num == @page do %>
<span class="px-3 py-2 bg-primary text-white rounded font-bold">
<%= page_num %>
</span>
<% else %>
<a
href={~p"/labels?page=#{page_num}"}
class="px-3 py-2 bg-secondary-light dark:bg-secondary-dark border border-gray-300 dark:border-gray-600 rounded text-fg-light dark:text-fg-dark hover:bg-primary hover:text-white transition"
>
<%= page_num %>
</a>
<% end %>
<% end %>
<% end %>
</div>
<%= if @page < @total_pages do %>
<a
href={~p"/labels?page=#{@page + 1}"}
class="px-4 py-2 bg-secondary-light dark:bg-secondary-dark border border-gray-300 dark:border-gray-600 rounded text-fg-light dark:text-fg-dark hover:bg-primary hover:text-white transition"
>
Next →
</a>
<% else %>
<span class="px-4 py-2 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded text-gray-400 dark:text-gray-600 cursor-not-allowed">
Next →
</span>
<% end %>
</div>
<% end %>
<% end %> <% end %>
</div> </div>

View File

@@ -29,7 +29,7 @@ defmodule LabelmakerWeb.LabelsControllerTest do
html = html_response(conn, 200) html = html_response(conn, 200)
assert html =~ "Generated Labels" assert html =~ "Generated Labels"
assert html =~ "Total labels: 3" assert html =~ "Showing 1-3 of 3 labels"
end end
test "displays label information correctly", %{conn: conn} do test "displays label information correctly", %{conn: conn} do
@@ -59,7 +59,7 @@ defmodule LabelmakerWeb.LabelsControllerTest do
html = html_response(conn, 200) html = html_response(conn, 200)
# Should show all labels # Should show all labels
assert html =~ "Total labels: 3" assert html =~ "Showing 1-3 of 3 labels"
end end
test "handles missing labels directory gracefully", %{conn: conn} do test "handles missing labels directory gracefully", %{conn: conn} do