diff --git a/app/queries/sponsors_search.rb b/app/queries/sponsors_search.rb index 45daad9a3..01dfdd289 100644 --- a/app/queries/sponsors_search.rb +++ b/app/queries/sponsors_search.rb @@ -29,9 +29,12 @@ def by_chapter return if chapter.blank? chapter_id = chapter.to_s.match?(/\A\d+\z/) ? chapter : lookup_chapter_id - return unless chapter_id - - @sponsors = sponsors.joins(:workshops).where('workshops.chapter_id' => chapter_id).group('sponsors.id') + if chapter_id + @sponsors = sponsors.joins(:workshops).where('workshops.chapter_id' => chapter_id).group('sponsors.id') + else + errors.add(:chapter, :not_found, message: 'no chapter with that name') + @sponsors = Sponsor.none + end end def lookup_chapter_id diff --git a/app/views/admin/sponsors/index.html.haml b/app/views/admin/sponsors/index.html.haml index 6cd7e5adb..6136cd3a2 100644 --- a/app/views/admin/sponsors/index.html.haml +++ b/app/views/admin/sponsors/index.html.haml @@ -1,17 +1,35 @@ +- title 'Sponsors' +%style= ".form-control::placeholder { opacity: 0.7; }" + .container.py-4.py-lg-5 .row.mb-4 .col-12 %nav{'aria-label': 'breadcrumb'} %ol.breadcrumb.ms-0 - %li.breadcrumb-item.active= t('admin.shared.sponsors') + %li.breadcrumb-item= link_to 'Admin', admin_root_path + %li.breadcrumb-item.active Sponsors + + .col-12 + %h1.mb-3 Sponsors .col-12 - .row.row-cols-md-auto.align-items-center - = form_with model: @sponsors_search, url: admin_sponsors_path, method: :get, class: 'row row-cols-1 row-cols-md-auto align-items-center' do |f| - = render(ChapterPickerComponent.new(name: 'sponsors_search[chapter]', chapters: @chapters, selected: @sponsors_search.chapter, placeholder: 'Filter by chapter')) - = f.text_field :name, placeholder: 'Filter by sponsor name', class: 'form-control w-auto my-2 my-md-0' - = f.button 'Filter', class: 'btn btn-primary' - = link_to 'Reset form', admin_sponsors_path + = form_with model: @sponsors_search, url: admin_sponsors_path, method: :get do |f| + %fieldset.border.rounded.bg-light.p-3 + %legend Filter sponsors + .row.row-cols-1.row-cols-md-auto.align-items-start.gap-1 + - chapter_error = @sponsors_search.errors[:chapter].any? + .col + = f.label :chapter, 'Chapter', class: 'form-label' + = render(ChapterPickerComponent.new(name: 'sponsors_search[chapter]', chapters: @chapters, selected: @sponsors_search.chapter, placeholder: 'ex: London')) + - if chapter_error + .invalid-feedback.d-block= @sponsors_search.errors[:chapter].join(', ') + .col + = f.label :name, 'Sponsor name', class: 'form-label' + = f.text_field :name, placeholder: 'ex: Google', class: 'form-control w-auto' + .col + .form-label.invisible   + = f.button 'Filter', class: 'btn btn-primary' + = link_to 'Reset form', admin_sponsors_path = render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'sponsor' } @@ -25,7 +43,7 @@ %th Level %th - Chapter(s) + Chapters %th Sponsorships %tbody @@ -40,5 +58,3 @@ = link_to chapter.name, admin_chapter_path(chapter) %td = sponsor.sponsorships_count - - = render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'sponsor' } diff --git a/app/views/shared/_pagination.html.haml b/app/views/shared/_pagination.html.haml index 78a7a983f..2c937447d 100644 --- a/app/views/shared/_pagination.html.haml +++ b/app/views/shared/_pagination.html.haml @@ -1,6 +1,6 @@ .row.align-items-center.justify-content-between .col-auto %p.mb-3 - != pagy.info_tag(item_name: model) + != pagy.info_tag(item_name: model.pluralize(pagy.count)) .col-auto != pagy.series_nav(:bootstrap) if pagy.pages > 1 diff --git a/spec/queries/sponsors_search_spec.rb b/spec/queries/sponsors_search_spec.rb index 49c1c1e8d..8acaa5b23 100644 --- a/spec/queries/sponsors_search_spec.rb +++ b/spec/queries/sponsors_search_spec.rb @@ -90,6 +90,16 @@ expect(results).to contain_exactly(matching) end + it 'returns an empty relation when chapter does not exist' do + Fabricate(:sponsor) + search = described_class.new(name: nil, chapter: 'Nonexistent') + + results = search.call + + expect(results).to be_empty + expect(search.errors[:chapter]).to include('no chapter with that name') + end + it 'returns an empty relation when nothing matches' do Fabricate(:sponsor, name: 'Apple Inc')