From 80c92f7e4f07b00bdca78566bb1c4a6274c5f3cb Mon Sep 17 00:00:00 2001
From: "joseph@dxw.com" <joseph@dxw.com>
Date: Mon, 18 Nov 2024 11:11:38 +0000
Subject: [PATCH] Drive tab change through a form

Following the same pattern we established for the zone selector, we remove the link from each tab and instead add a hidden form field and submit the form when a tab is clicked on.
---
 app/components/day_tab_component.html.erb     | 10 +---
 app/javascript/controllers/tab_controller.js  | 60 ++++---------------
 .../forecasts/_location_selector.html.erb     |  1 +
 spec/support/features/forecast_helper.rb      |  4 +-
 4 files changed, 17 insertions(+), 58 deletions(-)

diff --git a/app/components/day_tab_component.html.erb b/app/components/day_tab_component.html.erb
index cb167474..33bedf4a 100644
--- a/app/components/day_tab_component.html.erb
+++ b/app/components/day_tab_component.html.erb
@@ -1,16 +1,11 @@
 <%= tag.div class: "tab py-4 flex-1 #{@day} mx-2 px-1 text-center #{classes}",
   data: {
     date: @forecast.date.to_s,
-    controller: "tab",
-    "tab-active-class": "active",
-    "tab-inactive-class": "inactive",
+    day: @day,
     "tab-target": "dayPrediction",
+    action: "click->tab#changeTab",
   } do
   %>
-<%= link_to update_forecast_path(day: @day, format: :turbo_stream),
-      data: {
-        action: "click->tab#switch_tab click->map#updateMap",
-    } do %>
   <div class="day" data-tab-target="day">
     <%= @forecast.date == Date.today ? 'Today' : @forecast.date.strftime('%A') %>
   </div>
@@ -30,4 +25,3 @@
     Index <%= @forecast.air_pollution.value %>/10
   </div>
 <% end %>
-<% end %>
diff --git a/app/javascript/controllers/tab_controller.js b/app/javascript/controllers/tab_controller.js
index 5d5a4fde..93beaf47 100644
--- a/app/javascript/controllers/tab_controller.js
+++ b/app/javascript/controllers/tab_controller.js
@@ -1,59 +1,23 @@
 import { Controller } from "@hotwired/stimulus";
 
 // Connects to data-controller="tab"
-export default class extends Controller {
-  static classes = ["active", "inactive"];
-  static targets = ["dayPrediction", "day", "daqiValue"];
+export default class TabController extends Controller {
+  static targets = ["daySelector"];
 
   connect() {}
 
-  switch_tab() {
-    this.makeAllTabsInactive();
-    this.removeDaqiAlertClasses();
+  changeTab(event) {
+    const selectedDay = event.currentTarget.dataset.day;
 
-    this.addAlertClassIfNotTodayAndHasAirQualityAlert();
-    this.dayPredictionTarget.classList.toggle(this.activeClass);
-    this.dayPredictionTarget.classList.toggle(this.inactiveClass);
-  }
-
-  makeAllTabsInactive() {
-    document.querySelectorAll(".tabs .tab").forEach((el) => {
-      el.classList.remove(this.activeClass);
-      el.classList.add(this.inactiveClass);
-    });
-  }
-
-  addAlertClassIfNotTodayAndHasAirQualityAlert() {
-    const daqiValue = this.getDaqiValue();
-    if (this.dayTarget.innerText !== "Today" && daqiValue > 3) {
-      this.addDaqiAlertClass();
-    }
-  }
+    // Add the new date to the URL
+    const url = new URL(window.location.href);
+    url.searchParams.set("day", selectedDay);
+    window.history.pushState({}, "", url);
 
-  addDaqiAlertClass() {
-    const daqiValue = this.getDaqiValue();
-    this.dayPredictionTarget.classList.add(
-      `daqi-alert-after-today-selected-level-${daqiValue}`
-    );
-  }
-
-  removeDaqiAlertClasses() {
-    document.querySelectorAll(".tabs .tab").forEach((el) => {
-      const daqiAlertClassRegex = new RegExp(
-        "daqi-alert-after-today-selected-level-(\\d{1,2})"
-      );
-
-      const fullClassName = Array.from(el.classList).find((className) =>
-        className.match(daqiAlertClassRegex)
-      );
-
-      if (fullClassName) {
-        el.classList.remove(fullClassName);
-      }
-    });
-  }
+    // Update contents of daySelector
+    this.daySelectorTarget.value = selectedDay;
 
-  getDaqiValue() {
-    return this.daqiValueTarget.innerText.split("/")[0].split(" ")[1];
+    // Submit the form to reload the turbo frame
+    this.daySelectorTarget.form.requestSubmit();
   }
 }
diff --git a/app/views/forecasts/_location_selector.html.erb b/app/views/forecasts/_location_selector.html.erb
index 88eed19b..24a213f0 100644
--- a/app/views/forecasts/_location_selector.html.erb
+++ b/app/views/forecasts/_location_selector.html.erb
@@ -5,5 +5,6 @@
     class: "inline-flex flex-row w-full justify-left gap-x-1.5 rounded-md bg-white px-3 py-2 text-base font-semibold text-gray-500 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50",
     data: { controller: "prediction", "prediction-target": "zoneSelector", action: "change->prediction#changeZone" }
     %>
+    <%= hidden_field_tag :day, @day, data: { "tab-target": "daySelector" } %>
   <% end %>
 </div>
diff --git a/spec/support/features/forecast_helper.rb b/spec/support/features/forecast_helper.rb
index 87ac0f02..8ffcf299 100644
--- a/spec/support/features/forecast_helper.rb
+++ b/spec/support/features/forecast_helper.rb
@@ -13,9 +13,9 @@ def view_forecasts
     def switch_to_tab_for(day)
       case day
       when :tomorrow
-        find(".tab.tomorrow a").trigger("click")
+        find(".tab.tomorrow").trigger("click")
       when :day_after_tomorrow
-        find(".tab.day_after_tomorrow a").trigger("click")
+        find(".tab.day_after_tomorrow").trigger("click")
       else
         raise "day: #{day} not expected"
       end