diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb
index 6ac482fef..46aceb650 100644
--- a/app/controllers/locations_controller.rb
+++ b/app/controllers/locations_controller.rb
@@ -6,9 +6,12 @@ class LocationsController < ApplicationController
before_action :find_scheme
before_action :authenticate_action!
+ include Modules::SearchFilter
+
def index
- @pagy, @locations = pagy(@scheme.locations)
+ @pagy, @locations = pagy(filtered_collection(@scheme.locations, search_term))
@total_count = @scheme.locations.size
+ @searched = search_term.presence
end
def new
@@ -19,7 +22,12 @@ class LocationsController < ApplicationController
if date_params_missing?(location_params) || valid_date_params?(location_params)
@location = Location.new(location_params)
if @location.save
- location_params[:add_another_location] == "Yes" ? redirect_to(new_location_path(id: @scheme.id)) : redirect_to(scheme_check_answers_path(scheme_id: @scheme.id))
+ if location_params[:add_another_location] == "Yes"
+ redirect_to new_location_path(@scheme)
+ else
+ check_answers_path = @scheme.confirmed? ? scheme_check_answers_path(@scheme, anchor: "locations") : scheme_check_answers_path(@scheme)
+ redirect_to check_answers_path
+ end
else
render :new, status: :unprocessable_entity
end
@@ -92,4 +100,8 @@ private
required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode]
required_params
end
+
+ def search_term
+ params["search"]
+ end
end
diff --git a/app/models/location.rb b/app/models/location.rb
index 4812e2cd5..22d3b9607 100644
--- a/app/models/location.rb
+++ b/app/models/location.rb
@@ -7,6 +7,10 @@ class Location < ApplicationRecord
attr_accessor :add_another_location
+ scope :search_by_postcode, ->(postcode) { where("postcode ILIKE ?", "%#{postcode.gsub(/\s+/, '')}%") }
+ scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
+ scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) }
+
MOBILITY_TYPE = {
"Wheelchair-user standard": "W",
"Fitted with equipment and adaptations": "A",
diff --git a/app/views/locations/index.html.erb b/app/views/locations/index.html.erb
index 891b4c320..f8b02397d 100644
--- a/app/views/locations/index.html.erb
+++ b/app/views/locations/index.html.erb
@@ -1,3 +1,4 @@
+<% item_label = format_label(@pagy.count, "location") %>
<% title = @scheme.service_name %>
<% content_for :title, title %>
@@ -12,9 +13,13 @@
<%= render SubNavigationComponent.new(items: scheme_items(request.path, @scheme.id, "Locations")) %>
+<%= render SearchComponent.new(current_user:, search_label: "Search by location name or postcode", value: @searched) %>
+
+<%= govuk_section_break(visible: true, size: "m") %>
+
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
- <%= @scheme.locations.count %> <%= @scheme.locations.count.eql?(1) ? "location" : "locations" %>
+ <%= render(SearchResultCaptionComponent.new(searched: @searched, count: @pagy.count, item_label:, total_count: @total_count, item: "locations", path: request.path)) %>
<% end %>
<%= table.head do |head| %>
<%= head.row do |row| %>
diff --git a/app/views/organisations/_organisation_list.html.erb b/app/views/organisations/_organisation_list.html.erb
index c16366d19..68b8f3233 100644
--- a/app/views/organisations/_organisation_list.html.erb
+++ b/app/views/organisations/_organisation_list.html.erb
@@ -1,8 +1,8 @@
<%= govuk_table do |table| %>
<%= table.caption(classes: %w[govuk-!-font-size-19 govuk-!-font-weight-regular]) do |caption| %>
- <%= render(SearchResultCaptionComponent.new(searched:, count: pagy.count, item_label:, total_count:, item: "organisations", path: request.path)) %>
- <% end %>
+ <%= render(SearchResultCaptionComponent.new(searched:, count: pagy.count, item_label:, total_count:, item: "organisations", path: request.path)) %>
+ <% end %>
<%= table.head do |head| %>
<%= head.row do |row| %>
<% row.cell(header: true, text: "Name", html_attributes: {
diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb
index 4001b5c05..f3495dc35 100644
--- a/spec/features/schemes_spec.rb
+++ b/spec/features/schemes_spec.rb
@@ -202,6 +202,47 @@ RSpec.describe "Schemes scheme Features" do
end
end
end
+
+ context "when I search for a specific location" do
+ before do
+ click_link("Locations")
+ end
+
+ it "there is a search bar with a message and search button for locations" do
+ expect(page).to have_field("search")
+ expect(page).to have_content("Search by location name or postcode")
+ expect(page).to have_button("Search")
+ end
+
+ context "when I fill in search information and press the search button" do
+ let(:postcode_to_search) { "NW38RR" }
+ let(:location_name_to_search) { "search name location" }
+ let(:location_to_search) { FactoryBot.create(:location, postcode: postcode_to_search, name: location_name_to_search, scheme:) }
+
+ before do
+ fill_in("search", with: location_to_search.name)
+ click_button("Search")
+ end
+
+ it "displays scheme matching the location name" do
+ expect(page).to have_content(location_name_to_search)
+ end
+
+ context "when I want to clear results" do
+ it "there is link to clear the search results" do
+ expect(page).to have_link("Clear search")
+ end
+
+ it "displays all schemes after I clear the search results" do
+ click_link("Clear search")
+ Location.all.each do |location|
+ expect(page).to have_content(location.name)
+ end
+ end
+ end
+ end
+ end
+
end
end
end
diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb
index e5feaec24..9cebd09ef 100644
--- a/spec/models/location_spec.rb
+++ b/spec/models/location_spec.rb
@@ -55,4 +55,32 @@ RSpec.describe Location, type: :model do
.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Type of unit Select the most common type of unit at this location")
end
end
+
+ describe "scopes" do
+ before do
+ FactoryBot.create(:location, name: "ABC", postcode: "NW18RR")
+ FactoryBot.create(:location, name: "XYZ", postcode: "SE16HJ")
+ end
+
+ context "when searching by name" do
+ it "returns case insensitive matching records" do
+ expect(described_class.search_by_name("abc").count).to eq(1)
+ expect(described_class.search_by_name("AbC").count).to eq(1)
+ end
+ end
+
+ context "when searching by postcode" do
+ it "returns case insensitive matching records" do
+ expect(described_class.search_by_postcode("se1 6hj").count).to eq(1)
+ expect(described_class.search_by_postcode("SE1 6HJ").count).to eq(1)
+ end
+ end
+
+ context "when searching by all searchable field" do
+ it "returns case insensitive matching records" do
+ expect(described_class.search_by("aBc").count).to eq(1)
+ expect(described_class.search_by("nw18rr").count).to eq(1)
+ end
+ end
+ end
end