diff --git a/app/controllers/cities_controller.rb b/app/controllers/cities_controller.rb index 6f616d9..a89ab26 100644 --- a/app/controllers/cities_controller.rb +++ b/app/controllers/cities_controller.rb @@ -6,6 +6,10 @@ class CitiesController < ApplicationController @regions = Region.includes(:countries).order(:name) @cities = City.includes(:country, country: :region).order(:name) + if params[:query].present? + @cities = @cities.search_by_name(params[:query]) + end + if params[:region] @current_region = Region.friendly.find(params[:region]) @cities = @cities.by_region(@current_region.id) if @current_region diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index e099ff0..f0137f8 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -6,7 +6,9 @@ import { application } from "./application" import HelloController from "./hello_controller" import PhotoSwipeLightBoxController from "./photo_swipe_lightbox_controller" import FlashMessageController from "./flash_controller" +import SearchController from "./search_controller" application.register("hello", HelloController) application.register("photo-swipe-lightbox", PhotoSwipeLightBoxController) application.register("flash", FlashMessageController) +application.register("search", SearchController) diff --git a/app/javascript/controllers/search_controller.js b/app/javascript/controllers/search_controller.js new file mode 100644 index 0000000..bcfed0e --- /dev/null +++ b/app/javascript/controllers/search_controller.js @@ -0,0 +1,13 @@ +// app/javascript/controllers/search_controller.js +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["input"] + + submit() { + clearTimeout(this.timeout) + this.timeout = setTimeout(() => { + this.element.requestSubmit() + }, 300) + } +} \ No newline at end of file diff --git a/app/models/city.rb b/app/models/city.rb index c66e452..be8d9b1 100644 --- a/app/models/city.rb +++ b/app/models/city.rb @@ -97,6 +97,15 @@ class City < ApplicationRecord .order("COUNT(ahoy_events.id) DESC, cities.name ASC").limit(limit) end } + scope :search_by_name, ->(query) { + return all if query.blank? + + decoded_query = URI.decode_www_form_component(query).downcase + + where( + "LOWER(cities.name) LIKE :query", query: "%#{decoded_query}%" + ) + } def to_s diff --git a/app/views/cities/_search_city.html.erb b/app/views/cities/_search_city.html.erb new file mode 100644 index 0000000..9264924 --- /dev/null +++ b/app/views/cities/_search_city.html.erb @@ -0,0 +1,30 @@ +
+ <%= form_with url: cities_path, method: :get, class: "relative", data: { controller: "search" } do |f| %> +
+
+ + + +
+ <%= f.text_field :query, + value: params[:query] ? URI.decode_www_form_component(params[:query]) : nil, + class: "w-full pl-12 pr-4 py-3 rounded-full bg-base-200/50 backdrop-blur-sm border border-base-300 focus:outline-none focus:ring-2 focus:ring-primary/50", + placeholder: "Search cities...", + autocomplete: "off", + data: { + action: "input->search#submit", + search_target: "input" + } %> + <% if params[:query].present? %> + <%= link_to cities_path, class: "absolute inset-y-0 right-0 flex items-center pr-4" do %> + + + + <% end %> + <% end %> +
+ + <%= f.hidden_field :region, value: params[:region] if params[:region] %> + <%= f.hidden_field :country, value: params[:country] if params[:country] %> + <% end %> +
\ No newline at end of file diff --git a/app/views/cities/index.html.erb b/app/views/cities/index.html.erb index b94cdf2..b80509e 100644 --- a/app/views/cities/index.html.erb +++ b/app/views/cities/index.html.erb @@ -22,6 +22,8 @@ Discover AI-generated weather art from cities around the world

+ <%= render 'cities/search_city' %> + <% if featured_art %>
@@ -99,7 +101,7 @@ <% end %>
-
+
+ +
-
- <%= render partial: 'city', collection: @cities %> -
+ + <% if @cities.empty? %> +
+
+ + + +

No cities found

+

+ Try adjusting your search or filters to find what you're looking for. +

+
+
+ <% else %> + +
+ <%= render partial: 'city', collection: @cities %> +
+ <% end %> <%= render 'shared/pagination', collection: @cities,