Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ group :development, :test do
gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"

# Static analysis for security vulnerabilities [https://brakemanscanner.org/]
gem "brakeman", require: false
gem "brakeman", ">= 8.0", require: false

# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
gem "rubocop-rails-omakase", require: false
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ GEM
bindex (0.8.1)
bootsnap (1.18.6)
msgpack (~> 1.2)
brakeman (7.1.1)
brakeman (8.0.4)
racc
builder (3.3.0)
capybara (3.40.0)
Expand Down Expand Up @@ -429,7 +429,7 @@ PLATFORMS
DEPENDENCIES
activerecord-postgis-adapter
bootsnap
brakeman
brakeman (>= 8.0)
capybara
debug
hotwire-spark
Expand Down
5 changes: 5 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
* Consider organizing styles into separate files for maintainability.
*/

/* Ensure turbo-frame elements display as block */
turbo-frame {
display: block;
}

#map {
margin-bottom: 2rem;
height: 40vh;
Expand Down
46 changes: 23 additions & 23 deletions app/views/dashboard/_address_search.html.erb
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
<turbo-frame id="main-panel">
<div class="w-full px-4 py-4">
<div class="bg-gray-50 rounded-lg shadow-sm max-w-xl mx-auto p-4 sm:p-6">
<%= form_with url: dashboard_panel_path('address_search'), method: :post, data: { turbo_frame: 'main-panel' }, html: { class: "space-y-4" } do |form| %>
<div class="relative">
<%= form.label :address, "Enter your address", class: "block text-sm font-medium text-gray-700 mb-1" %>
<%= form.text_field :address, placeholder: "e.g., 123 Main St, City, State, Zip Code", class: "w-full py-3 px-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", autocomplete: "off" %>
</div>
<div class="flex justify-center w-full mb-4">
<%= form.submit "Find My Representatives", class: "inline-flex items-center bg-blue-500 hover:bg-blue-700 text-white font-semibold py-3 px-4 border border-blue-700 rounded-lg text-base sm:text-lg" %>
</div>
<% end %>

<%# Support both locals and instance variables for Turbo and non-Turbo renders %>
<% reps = (defined?(representatives) ? representatives : @representatives) %>
<% did_search = (defined?(searched) ? searched : @searched) %>
<% if did_search %>
<div class="mt-6 mb-2 w-full">
<div class="w-full overflow-x-auto md:overflow-visible">
<%= render partial: 'representatives_table', locals: { representatives: reps } %>
</div>
</div>
<% end %>
<turbo-frame id="main-panel" class="block w-full">
<div class="bg-white rounded-lg shadow-sm p-4 sm:p-6">
<div class="bg-gray-50 rounded-lg max-w-xl mx-auto p-4 sm:p-6">
<%= form_with url: dashboard_panel_path('address_search'), method: :post, data: { turbo_frame: 'main-panel' }, html: { class: "space-y-4" } do |form| %>
<div class="relative">
<%= form.label :address, "Enter your address", class: "block text-sm font-medium text-gray-700 mb-1" %>
<%= form.text_field :address, placeholder: "e.g., 123 Main St, City, State, Zip Code", class: "w-full py-3 px-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", autocomplete: "off" %>
</div>
<div class="flex justify-center w-full">
<%= form.submit "Find My Representatives", class: "inline-flex items-center bg-blue-500 hover:bg-blue-700 text-white font-semibold py-3 px-4 border border-blue-700 rounded-lg text-base sm:text-lg cursor-pointer" %>
</div>
<% end %>
</div>

<%# Support both locals and instance variables for Turbo and non-Turbo renders %>
<% reps = (defined?(representatives) ? representatives : @representatives) %>
<% did_search = (defined?(searched) ? searched : @searched) %>
<% if did_search %>
<div class="mt-6 w-full">
<div class="w-full -mx-4 sm:mx-0">
<%= render partial: 'representatives_table', locals: { representatives: reps } %>
</div>
</div>
<% end %>
</div>
</turbo-frame>
12 changes: 5 additions & 7 deletions app/views/dashboard/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
<div class="min-h-screen bg-gray-50 px-3 py-4 sm:p-6 container max-w-6xl mx-auto">
<div class="flex flex-col md:flex-row gap-4 sm:gap-6 mb-6 sm:mb-8 md:mx-4">
<div class="order-1 md:order-1 w-full md:w-1/3 bg-white rounded-lg shadow-sm p-4 sm:p-6 flex flex-col justify-between mb-6 md:mb-0">
<div class="w-full md:w-1/3 bg-white rounded-lg shadow-sm p-4 sm:p-6 flex flex-col justify-between">
<%= render 'dashboard/home' %>
</div>
<div class="order-3 md:order-2 w-full md:w-2/3 bg-white rounded-lg shadow-sm p-4 sm:p-6">
<div class="w-full md:w-2/3 bg-white rounded-lg shadow-sm p-4 sm:p-6">
<%= render 'dashboard/progress_map' %>
</div>
</div>
<turbo-frame id="main-panel" class="order-2 md:order-3 w-full">
<div class="bg-white rounded-lg shadow-sm p-4 sm:p-6">
<%= render 'dashboard/address_search' %>
</div>
</turbo-frame>
<div class="md:mx-4">
<%= render 'dashboard/address_search' %>
</div>
</div>
14 changes: 8 additions & 6 deletions app/views/representatives/_representatives_table.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<%# app/views/pages/_representatives_table.html.erb %>
<% if representatives.present? %>
<div class="overflow-x-auto md:overflow-visible border border-gray-200 rounded-lg shadow-sm mb-8">
<table id="reps-table" class="w-full table-auto text-xs sm:text-sm">
<div class="overflow-x-auto border border-gray-200 rounded-lg shadow-sm mb-4 sm:mb-8">
<table id="reps-table" class="w-full table-auto text-xs sm:text-sm min-w-full">
<thead class="hidden md:table-header-group">
<tr class="bg-gray-50 border-b border-gray-200">
<th class="w-24 px-2 sm:px-4 py-2 sm:py-3 text-center text-[10px] sm:text-xs font-medium text-gray-500 uppercase tracking-wide border-b-2 border-gray-200 whitespace-normal break-words">Image</th>
Expand All @@ -11,11 +11,11 @@
<th class="w-16 md:w-14 px-1 sm:px-3 py-2 sm:py-3 text-center text-[10px] sm:text-xs font-medium text-gray-500 uppercase tracking-wide border-b-2 border-gray-200 whitespace-normal break-words">Links</th>
</tr>
</thead>
<tbody class="bg-white">
<tbody class="bg-white divide-y divide-gray-200">
<% representatives.each do |rep_obj| %>
<% rep = rep_obj.is_a?(Hash) ? rep_obj : rep_obj.respond_to?(:data) ? rep_obj.data : {} %>
<% initials = rep["name"].to_s.split.size >= 2 ? rep["name"].to_s.split.first[0] + rep["name"].to_s.split.last[0] : rep["name"].to_s[0,2] rescue '??' %>
<tr class="block md:table-row border-b-2 border-gray-200 mb-2 md:mb-0 hover:bg-gray-50">
<tr class="block md:table-row border-b border-gray-200 py-4 md:py-0 hover:bg-gray-50">
<td class="text-center block md:table-cell px-3 py-2 md:pl-8 md:pr-5 md:py-3.5 whitespace-nowrap align-center">
<% if rep["image"] %>
<div class="flex justify-center p-1 sm:p-2">
Expand Down Expand Up @@ -102,9 +102,11 @@
</tbody>
</table>
</div>
<div class="text-center py-3 sm:py-4 text-xs sm:text-sm text-gray-600 border-t border-gray-200 mt-3 sm:mt-4">
<div class="text-center py-3 sm:py-4 text-xs sm:text-sm text-gray-600">
↑ Scroll up to search for a different address
</div>
<% else %>
<p class="text-gray-500 text-center py-4">No representatives found.</p>
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 sm:p-6 text-center">
<p class="text-gray-600 text-sm sm:text-base">No representatives found for this address. Please try a different address.</p>
</div>
<% end %>
Loading