Skip to content

Commit

Permalink
Use date rather than day in the URL
Browse files Browse the repository at this point in the history
Currently we store the day ('today', 'tomorrow', etc.) in the URL. If the user shares the tomorrow URL on Monday and the recipient clicks on Tuesday, they will see the forecast for Wednesday.

This change means we store the date ('2024-11-20') instead. If the date is outside of the bounds of the three day forecast, we fall back to the nearest day (so today for past dates and day after tomorrow for future dates).

The former URLs with day will still work, but date takes precedence.
  • Loading branch information
jdudley1123 committed Nov 20, 2024
1 parent 19f1cfa commit ee0f425
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 12 deletions.
15 changes: 14 additions & 1 deletion app/controllers/forecasts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@ 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)
end

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"
Expand Down
6 changes: 3 additions & 3 deletions app/javascript/controllers/forecast_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/controllers/map_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down
6 changes: 1 addition & 5 deletions app/views/forecasts/_forecast_tabs.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<h3 class="text-xl font-bold mt-4 mb-2"> Air pollution for <%= @zone.name %></h3>
<div
class="tabs"
data-turbo-prefetch="false"
data-map-target="daySelector"
>
<div class="tabs">
<%= 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')) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/forecasts/_location_selector.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
49 changes: 48 additions & 1 deletion spec/controllers/forecasts_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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

0 comments on commit ee0f425

Please sign in to comment.