Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to specify and change location #110

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
Open
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: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,5 @@ end
gem "cssbundling-rails", "~> 1.4"
gem "stimulus-rails"
gem "jsbundling-rails", "~> 1.3"

gem "turbo_power", "~> 0.6.2"
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ GEM
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
turbo_power (0.6.2)
turbo-rails (>= 1.3.0)
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
Expand Down Expand Up @@ -493,6 +495,7 @@ DEPENDENCIES
stimulus-rails
terser
turbo-rails
turbo_power (~> 0.6.2)
turbolinks (~> 5)
tzinfo-data
view_component
Expand Down
12 changes: 4 additions & 8 deletions app/components/day_tab_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
<%= tag.div class: "tab py-4 flex-1 #{@day} mx-2 px-1 text-center #{classes}",
<%= tag.div class: "tab py-4 flex-1 #{@day} mx-2 px-1 text-center #{tab_classes}",
data: {
date: @forecast.date.to_s,
controller: "tab",
"tab-active-class": "active",
"tab-inactive-class": "inactive",
"tab-target": "dayPrediction",
"map-target": "daySelector",
} do
%>
<%= link_to update_forecast_path(day: @day, format: :turbo_stream),
<%= link_to update_forecast_path(day: @day, zone: @zone.name, format: :turbo_stream),
data: {
action: "click->tab#switch_tab click->map#updateMap",
} do %>
<div class="day" data-tab-target="day">
<div class="day">
<%= @forecast.date == Date.today ? 'Today' : @forecast.date.strftime('%A') %>
</div>
<div class="date">
Expand All @@ -27,7 +23,7 @@
<div class="daqi-label text-base">
<%= @forecast.air_pollution.label.capitalize %>
</div>
<div class="daqi-value font-normal" data-tab-target="daqiValue">
<div class="daqi-value font-normal">
Index <%= @forecast.air_pollution.value %>/10
</div>
<% end %>
Expand Down
26 changes: 21 additions & 5 deletions app/components/day_tab_component.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
class DayTabComponent < ViewComponent::Base
def initialize(forecast:, day:)
def initialize(forecast:, day:, selected_day:)
@forecast = forecast
@day = day
@selected_day = selected_day
@zone = forecast.zone
end

TAG_COLOURS = {
Expand All @@ -21,11 +23,25 @@ def daqi_indicator_colour_class
TAG_COLOURS.fetch(@forecast.air_pollution.value)
end

def classes
if @day == :today
"active daqi-level-#{@forecast.air_pollution.value}-today"
def daqi_tab_class
if @day == "today"
"daqi-level-#{@forecast.air_pollution.value}-today"
elsif @forecast.alerts && @day == @selected_day
"daqi-alert-after-today-selected-level-#{@forecast.air_pollution.value}"
else
"inactive after-today"
"after-today"
end
end

def active_tab_class
if @day == @selected_day
"active"
else
"inactive"
end
end

def tab_classes
"#{daqi_tab_class} #{active_tab_class}"
end
end
29 changes: 22 additions & 7 deletions app/controllers/forecasts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
class ForecastsController < ApplicationController
def show
@selected_day = selected_day
@zone = zone

@maptiler_api_key = ENV.fetch("MAPTILER_API_KEY")
@forecasts = CercForecastService.latest_forecasts_for(zone).data
@forecasts = CercForecastService.latest_forecasts_for(@zone).data
@day_forecast = forecast_for_day(@selected_day, @forecasts)
end

def update
@selected_day = selected_day
@zone = zone

@maptiler_api_key = ENV.fetch("MAPTILER_API_KEY")
forecasts = CercForecastService.latest_forecasts_for(zone).data
@forecasts = CercForecastService.latest_forecasts_for(@zone).data

@day_forecast = forecast_for_day(params.fetch("day"), forecasts)
@day_forecast = forecast_for_day(@selected_day, @forecasts)

respond_to do |format|
format.turbo_stream
Expand All @@ -25,14 +32,22 @@ def forecast_for_day(day, forecasts)
forecasts.second
when "day_after_tomorrow"
forecasts.third
else
raise ArgumentError, "Invalid day: #{day}"
end
end

def zone
return Zone.default unless params[:zone]
if params[:zone]
Zone.find_by(name: params[:zone]) || Zone.default
else
Zone.default
end
end

Zone.find_by(cerc_id: params[:zone])
def selected_day
if ["today", "tomorrow", "day_after_tomorrow"].include?(params[:day])
params[:day]
else
"today"
end
end
end
13 changes: 9 additions & 4 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import * as Turbo from "@hotwired/turbo";

import TurboPower from "turbo_power";
TurboPower.initialize(Turbo.StreamActions);

document.addEventListener("DOMContentLoaded", function () {
const hamburgerMenu = document.getElementById("hamburger-menu");
Expand All @@ -19,9 +22,11 @@ document.addEventListener("DOMContentLoaded", function () {

locationList &&
locationList.addEventListener("click", function (e) {
const newSelectedZone = e.target.innerText;
const selectedZone = document.getElementById("selected-zone");
selectedZone.innerText = newSelectedZone;
const selectedZone = e.target.innerText;
const selectedZoneInput = document.getElementById("zone");
selectedZoneInput.value = selectedZone;
const selectedZoneLabel = document.getElementById("selected-zone-label");
selectedZoneLabel.innerText = selectedZone;
locationList.classList.toggle("hidden");
});
});
Expand Down
3 changes: 0 additions & 3 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,3 @@ application.register("map", MapController);

import PredictionController from "./prediction_controller";
application.register("prediction", PredictionController);

import TabController from "./tab_controller";
application.register("tab", TabController);
59 changes: 0 additions & 59 deletions app/javascript/controllers/tab_controller.js

This file was deleted.

18 changes: 8 additions & 10 deletions app/views/forecasts/_alert_guidance.html.erb
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<%= turbo_frame_tag "alert_guidance" do %>
<% if air_pollution_prediction.air_quality_alert %>
<div class="alert-guidance bg-<%= air_pollution_prediction.air_quality_alert.daqi_label.parameterize %>-alert-guidance-panel m-5 p-10">
<p class="font-semibold mb-4">
<%= t("air_quality_alert.#{air_pollution_prediction.air_quality_alert.daqi_level}.guidance.title") %>
</p>
<div class="text-xs">
<%= t("air_quality_alert.#{air_pollution_prediction.air_quality_alert.daqi_level}.guidance.detail_html") %>
</div>
<% if air_pollution_prediction.air_quality_alert %>
<div class="alert-guidance bg-<%= air_pollution_prediction.air_quality_alert.daqi_label.parameterize %>-alert-guidance-panel m-5 p-10">
<p class="font-semibold mb-4">
<%= t("air_quality_alert.#{air_pollution_prediction.air_quality_alert.daqi_level}.guidance.title") %>
</p>
<div class="text-xs">
<%= t("air_quality_alert.#{air_pollution_prediction.air_quality_alert.daqi_level}.guidance.detail_html") %>
</div>
<% end %>
</div>
<% end %>
14 changes: 0 additions & 14 deletions app/views/forecasts/_forecast_tabs.html.erb

This file was deleted.

9 changes: 5 additions & 4 deletions app/views/forecasts/_location.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
</h2>
</div>
<div class="location p-4 pt-2">
<%= render partial: "location_selector" %>
<a href="#" class="change-location block underline text-xs">
Change location
</a>
<%= form_with url: update_forecast_path(format: :turbo_stream), method: :get do |form| %>
<%= render partial: "location_selector", locals: {form: form, selected_zone: @zone} %>
<%= render partial: "selected_day_input", locals: {selected_day: @selected_day} %>
<%= form.submit "Change location", class: "change-location block underline text-xs cursor-pointer" %>
<% end %>
</div>
8 changes: 4 additions & 4 deletions app/views/forecasts/_location_selector.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z" />
</svg>
<span id="selected-zone" class="ml-3 block truncate">Southwark, London</span>
<span id="selected-zone-label" class="ml-3 block truncate"><%= selected_zone.name %></span>
<%= hidden_field_tag "zone", selected_zone.name %>
</span>
<span class="pointer-events-none absolute inset-y-0 right-0 ml-3 flex items-center pr-2">
<svg class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
Expand All @@ -32,16 +33,15 @@

Highlighted: "bg-indigo-600 text-white", Not Highlighted: "text-gray-900"
-->
<% zones = JSON.parse(File.read(Rails.root.join('config', 'list-of-zones.json'))).map(&:to_s) %>
<% zones.each do |zone| %>
<% Zone.all.each do |zone| %>
<li class="relative cursor-default select-none py-2 pl-3 pr-9 text-gray-900" id="listbox-option-0" role="option">
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z" />
</svg>
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
<span class="ml-3 block truncate font-normal"><%= zone %></span>
<span class="ml-3 block truncate font-normal"><%= zone.name %></span>
</div>
</li>
<% end %>
Expand Down
16 changes: 16 additions & 0 deletions app/views/forecasts/_pollution_forecast.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%= turbo_frame_tag "pollution_forecast" do %>
<div class="air-pollution my-4">
<header class="text-xl px-4 font-bold">
Air pollution
</header>
<div
class="tabs flex flex-row items-stretch mt-4 m-1 text-xs font-bold border-b-[3px] border-black"
data-turbo-prefetch="false"
>
<%= render(DayTabComponent.new(forecast: forecasts.first, day: "today", selected_day: selected_day)) %>
<%= render(DayTabComponent.new(forecast: forecasts.second, day: "tomorrow", selected_day: selected_day)) %>
<%= render(DayTabComponent.new(forecast: forecasts.third, day: "day_after_tomorrow", selected_day: selected_day)) %>
</div>
<%= render partial: "alert_guidance", locals: {air_pollution_prediction: day_forecast} %>
</div>
<% end %>
3 changes: 3 additions & 0 deletions app/views/forecasts/_selected_day_input.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= turbo_frame_tag "selected_day_input" do %>
<%= hidden_field_tag "day", selected_day %>
<% end %>
4 changes: 2 additions & 2 deletions app/views/forecasts/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div data-controller="map">
<%= render partial: "forecasts/location" %>
<%= render partial: "forecasts/forecast_tabs", cerc_forecasts: @forecasts %>
<%= render partial: "forecasts/pollution_forecast", locals: {forecasts: @forecasts, day_forecast: @day_forecast, selected_day: @selected_day} %>
<%= render partial: "forecasts/map" %>
<%= render partial: "forecasts/predictions", locals: { forecast: @forecasts.first } %>
<%= render partial: "forecasts/predictions", locals: { forecast: @day_forecast } %>
<%= render partial: "sharing" %>
</div>
<%= render partial: "learning" %>
Expand Down
4 changes: 3 additions & 1 deletion app/views/forecasts/update.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
<%= turbo_stream.replace("day_predictions", partial: "predictions", locals: {forecast: @day_forecast}) %>
<%= turbo_stream.replace("alert_guidance", partial: "alert_guidance", locals: {air_pollution_prediction: @day_forecast}) %>
<%= turbo_stream.replace("pollution_forecast", partial: "pollution_forecast", locals: {forecasts: @forecasts, day_forecast: @day_forecast, selected_day: @selected_day}) %>
<%= turbo_stream.replace("selected_day_input", partial: "selected_day_input", locals: {selected_day: @selected_day}) %>
<%= turbo_stream.push_state forecast_path(:day => @selected_day, :zone => @zone.name) %>
42 changes: 0 additions & 42 deletions config/list-of-zones.json

This file was deleted.

Loading