now with pagination
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user