[WV2] Improve pagination with page dropdown
Replace will_paginate's view helpers with a custom prev/next + page dropdown control. Layout: [← Prev] [Page <select> of N] [Next →] - Prev/Next are regular links (work without JS) - Dropdown wrapped in <auto-submit-form> for JS-enhanced navigation - "Go" submit button appears when JS is disabled - Single pagination bar at top of results (removed bottom duplicate) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4f2691ef43
commit
411be67a35
3 changed files with 117 additions and 2 deletions
|
|
@ -918,6 +918,86 @@ pose-picker-popover {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination-bar {
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
.pagination-prev,
|
||||||
|
.pagination-next {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background: white;
|
||||||
|
color: var(--color-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
box-shadow: 0 0 0 3px var(--color-primary-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
color: #ccc;
|
||||||
|
border-color: #eee;
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: white;
|
||||||
|
border-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-page-selector {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background: white;
|
||||||
|
color: var(--color-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 4rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
box-shadow: 0 0 0 3px var(--color-primary-muted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto-submit-form {
|
||||||
|
display: contents;
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===================================================================
|
/* ===================================================================
|
||||||
|
|
|
||||||
33
app/views/wardrobe/items/_pagination.html.haml
Normal file
33
app/views/wardrobe/items/_pagination.html.haml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
- # Local variables:
|
||||||
|
- # - collection: The WillPaginate collection (e.g., @search_results)
|
||||||
|
- # - url_params: The URL params hash (e.g., @outfit.wardrobe_params.merge(q: params[:q]))
|
||||||
|
|
||||||
|
- if collection.total_pages > 1
|
||||||
|
.pagination-bar
|
||||||
|
- if collection.previous_page
|
||||||
|
= link_to "← Prev", url_params.merge(page: collection.previous_page), class: "pagination-prev"
|
||||||
|
- else
|
||||||
|
%span.pagination-prev.disabled ← Prev
|
||||||
|
|
||||||
|
%auto-submit-form
|
||||||
|
= form_with url: @wardrobe_path, method: :get do |f|
|
||||||
|
- url_params.each do |key, value|
|
||||||
|
- if value.is_a?(Array)
|
||||||
|
- value.each do |v|
|
||||||
|
= hidden_field_tag "#{key}[]", v, id: nil
|
||||||
|
- else
|
||||||
|
= hidden_field_tag key, value, id: nil
|
||||||
|
|
||||||
|
%label.pagination-page-selector
|
||||||
|
Page
|
||||||
|
= select_tag :page,
|
||||||
|
options_for_select((1..collection.total_pages).map { |p| [p, p] }, collection.current_page),
|
||||||
|
"aria-label": "Page number"
|
||||||
|
of #{collection.total_pages}
|
||||||
|
|
||||||
|
= submit_tag "Go", name: nil, class: "progressive-submit"
|
||||||
|
|
||||||
|
- if collection.next_page
|
||||||
|
= link_to "Next →", url_params.merge(page: collection.next_page), class: "pagination-next"
|
||||||
|
- else
|
||||||
|
%span.pagination-next.disabled Next →
|
||||||
|
|
@ -3,14 +3,16 @@
|
||||||
.error-state
|
.error-state
|
||||||
%p.error-message= @search_error
|
%p.error-message= @search_error
|
||||||
- elsif @search_results.any?
|
- elsif @search_results.any?
|
||||||
= will_paginate @search_results, page_links: false, param_name: :page, params: @outfit.wardrobe_params.merge(q: params[:q])
|
- pagination_params = @outfit.wardrobe_params
|
||||||
|
- pagination_params = pagination_params.merge(q: params[:q]) if params[:q].present?
|
||||||
|
= render "items/pagination", collection: @search_results, url_params: pagination_params
|
||||||
|
|
||||||
%ul.search-results-list
|
%ul.search-results-list
|
||||||
- @search_results.each do |item|
|
- @search_results.each do |item|
|
||||||
- appearance = @appearances_by_item_id&.dig(item.id)
|
- appearance = @appearances_by_item_id&.dig(item.id)
|
||||||
= render "items/item_card", item: item, appearance: appearance
|
= render "items/item_card", item: item, appearance: appearance
|
||||||
|
|
||||||
= will_paginate @search_results, param_name: :page, params: @outfit.wardrobe_params.merge(q: params[:q])
|
= render "items/pagination", collection: @search_results, url_params: pagination_params
|
||||||
|
|
||||||
- else
|
- else
|
||||||
.empty-state
|
.empty-state
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue