diff --git a/app/controllers/forecasts_controller.rb b/app/controllers/forecasts_controller.rb
index 095e2ad7..7879696c 100644
--- a/app/controllers/forecasts_controller.rb
+++ b/app/controllers/forecasts_controller.rb
@@ -2,7 +2,8 @@ class ForecastsController < ApplicationController
def show
@maptiler_api_key = ENV.fetch("MAPTILER_API_KEY")
@zone = zone
- @day = params.fetch("day", "today")
+ @date = Date.parse(params.fetch("date")) if params[:date]
+ @day = @date ? day_from_date(@date) : params.fetch("day", "today")
@pollutant = params.fetch("pollutant", "Total")
@forecasts = CercForecastService.latest_forecasts_for(zone).data
@day_forecast = forecast_for_day(@day, @forecasts)
@@ -10,6 +11,18 @@ def show
private
+ def day_from_date(date)
+ if date <= Date.today
+ "today"
+ elsif date == Date.tomorrow
+ "tomorrow"
+ elsif date >= Date.tomorrow
+ "day_after_tomorrow"
+ else
+ "today"
+ end
+ end
+
def forecast_for_day(day, forecasts)
case day
when "today"
diff --git a/app/javascript/controllers/forecast_controller.js b/app/javascript/controllers/forecast_controller.js
index d31a8a20..a7f2d09f 100644
--- a/app/javascript/controllers/forecast_controller.js
+++ b/app/javascript/controllers/forecast_controller.js
@@ -9,12 +9,12 @@ export default class ForecastController extends Controller {
}
changeDay(event) {
- const selectedDay = event.currentTarget.dataset.day;
+ const selectedDate = event.currentTarget.dataset.date;
- this.updateUrl({ day: selectedDay });
+ this.updateUrl({ date: selectedDate });
// Update contents of daySelector
- this.daySelectorTarget.value = selectedDay;
+ this.daySelectorTarget.value = selectedDate;
this.reloadPrediction();
}
diff --git a/app/javascript/controllers/map_controller.js b/app/javascript/controllers/map_controller.js
index 65443a3d..fee019dc 100644
--- a/app/javascript/controllers/map_controller.js
+++ b/app/javascript/controllers/map_controller.js
@@ -26,7 +26,7 @@ export default class MapController extends Controller {
updateSettings() {
const pollutant = this.pollutantSelectorTarget.value;
- const date = this.daySelectorTarget.querySelector(".active").dataset.date;
+ const date = this.daySelectorTarget.value;
const url = new URL(window.location.href);
const lat = parseFloat(url.searchParams.get("lat"));
const lng = parseFloat(url.searchParams.get("lng"));
diff --git a/app/views/forecasts/_forecast_tabs.html.erb b/app/views/forecasts/_forecast_tabs.html.erb
index 0e3db44d..47646e71 100644
--- a/app/views/forecasts/_forecast_tabs.html.erb
+++ b/app/views/forecasts/_forecast_tabs.html.erb
@@ -1,9 +1,5 @@
Air pollution for <%= @zone.name %>
-
+
<%= render(DayTabComponent.new(forecast: @forecasts.first, day: 'today', active: @day == 'today')) %>
<%= render(DayTabComponent.new(forecast: @forecasts.second, day: 'tomorrow', active: @day == 'tomorrow')) %>
<%= render(DayTabComponent.new(forecast: @forecasts.third, day: 'day_after_tomorrow', active: @day == 'day_after_tomorrow')) %>
diff --git a/app/views/forecasts/_location_selector.html.erb b/app/views/forecasts/_location_selector.html.erb
index 8df08b64..27b685ec 100644
--- a/app/views/forecasts/_location_selector.html.erb
+++ b/app/views/forecasts/_location_selector.html.erb
@@ -3,5 +3,5 @@
options_for_select(Zone.all.order(:name).map(&:name), @zone.name),
data: { "forecast-target": "zoneSelector", action: "change->forecast#changeZone" }
%>
- <%= hidden_field_tag :day, @day, data: { "forecast-target": "daySelector" } %>
+ <%= hidden_field_tag :date, @date, data: { "forecast-target": "daySelector", "map-target": "daySelector" } %>
<% end %>
diff --git a/spec/controllers/forecasts_controller_spec.rb b/spec/controllers/forecasts_controller_spec.rb
index 6c1f025f..bb5a00e0 100644
--- a/spec/controllers/forecasts_controller_spec.rb
+++ b/spec/controllers/forecasts_controller_spec.rb
@@ -41,7 +41,7 @@
end
context "when a recognised _day_ parameter is received" do
- it "renders the turbo update template" do
+ it "renders the _show_ template" do
allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
get :show, params: {day: :today}
@@ -60,5 +60,52 @@
}.to raise_error(ArgumentError, "Invalid day: yesterday")
end
end
+
+ context "when a _date_ parameter is received" do
+ before do
+ allow(CercForecastService).to receive(:latest_forecasts_for).and_return(forecasts)
+ get :show, params: {date: date.to_s}
+ end
+
+ context "when the date is in the past" do
+ let(:date) { 5.day.ago.to_date }
+
+ it "shows the forecast for today" do
+ expect(assigns(:day_forecast)).to eq(forecasts.data.first)
+ end
+ end
+
+ context "when the date is today" do
+ let(:date) { Date.today }
+
+ it "shows the forecast for today" do
+ expect(assigns(:day_forecast)).to eq(forecasts.data.first)
+ end
+ end
+
+ context "when the date is tomorrow" do
+ let(:date) { Date.tomorrow }
+
+ it "shows the forecast for tomorrow" do
+ expect(assigns(:day_forecast)).to eq(forecasts.data.second)
+ end
+ end
+
+ context "when the date is the day after tomorrow" do
+ let(:date) { 2.days.from_now.to_date }
+
+ it "shows the forecast for the day after tomorrow" do
+ expect(assigns(:day_forecast)).to eq(forecasts.data.third)
+ end
+ end
+
+ context "when the date is in the future" do
+ let(:date) { 5.days.from_now.to_date }
+
+ it "shows the forecast for the day after tomorrow" do
+ expect(assigns(:day_forecast)).to eq(forecasts.data.third)
+ end
+ end
+ end
end
end