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