diff --git a/app/assets/stylesheets/wardrobe/show.css b/app/assets/stylesheets/wardrobe/show.css index 3329ea3b..56f7d9c1 100644 --- a/app/assets/stylesheets/wardrobe/show.css +++ b/app/assets/stylesheets/wardrobe/show.css @@ -918,6 +918,86 @@ pose-picker-popover { justify-content: center; 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; + } + } + } } /* =================================================================== diff --git a/app/views/wardrobe/items/_pagination.html.haml b/app/views/wardrobe/items/_pagination.html.haml new file mode 100644 index 00000000..df5d7ddc --- /dev/null +++ b/app/views/wardrobe/items/_pagination.html.haml @@ -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 → diff --git a/app/views/wardrobe/items/_search_results.html.haml b/app/views/wardrobe/items/_search_results.html.haml index ada84210..7b772ea2 100644 --- a/app/views/wardrobe/items/_search_results.html.haml +++ b/app/views/wardrobe/items/_search_results.html.haml @@ -3,14 +3,16 @@ .error-state %p.error-message= @search_error - 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 - @search_results.each do |item| - appearance = @appearances_by_item_id&.dig(item.id) = 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 .empty-state