Mattias Bodlund 1 week ago
parent
commit
46d24ac628
13 changed files with 407 additions and 19 deletions
  1. +8
    -8
      Gemfile.lock
  2. +1
    -0
      app/assets/images/ico-coins.svg
  3. +1
    -0
      app/assets/images/ico-fuel.svg
  4. +1
    -0
      app/assets/images/ico-thumb.svg
  5. +186
    -1
      app/assets/stylesheets/application.css
  6. +5
    -3
      app/controllers/game_controller.rb
  7. +63
    -0
      app/helpers/game_helper.rb
  8. +3
    -2
      app/models/node.rb
  9. +1
    -1
      app/views/game/done.html.erb
  10. +0
    -1
      app/views/game/result.html.erb
  11. +84
    -0
      app/views/game/results.html.erb
  12. +53
    -2
      config/locales/en.yml
  13. +1
    -1
      config/routes.rb

+ 8
- 8
Gemfile.lock View File

@ -152,7 +152,7 @@ GEM
kaminari-core (= 1.2.2)
kaminari-core (1.2.2)
language_server-protocol (3.17.0.5)
lexxy (0.9.15.alpha.4)
lexxy (0.9.17)
rails (>= 8.0.2)
lint_roller (1.1.0)
logger (1.7.0)
@ -175,7 +175,7 @@ GEM
mobility (1.3.2)
i18n (>= 0.6.10, < 2)
request_store (~> 1.0)
msgpack (1.8.1)
msgpack (1.8.2)
net-imap (0.6.4)
date
net-protocol
@ -311,7 +311,7 @@ GEM
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.47.1, < 2.0)
rubocop-rails (2.35.3)
rubocop-rails (2.35.4)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
@ -358,7 +358,7 @@ GEM
actionview (>= 8.0.0)
bindex (>= 0.4.0)
railties (>= 8.0.0)
websocket-driver (0.8.0)
websocket-driver (0.8.1)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
@ -462,7 +462,7 @@ CHECKSUMS
kaminari-activerecord (1.2.2) sha256=0dd3a67bab356a356f36b3b7236bcb81cef313095365befe8e98057dd2472430
kaminari-core (1.2.2) sha256=3bd26fec7370645af40ca73b9426a448d09b8a8ba7afa9ba3c3e0d39cdbb83ff
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
lexxy (0.9.15.alpha.4) sha256=7a0ee226537eca2e17a5466073dd4f6215a00339fcde78e54425e8150b55c125
lexxy (0.9.17) sha256=1a265ec2ecdb0cce621900b0886a44890f195c84e4c6b187c9812a25a60d16cf
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
loofah (2.25.1) sha256=d436c73dbd0c1147b16c4a41db097942d217303e1f7728704b37e4df9f6d2e04
@ -472,7 +472,7 @@ CHECKSUMS
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
mobility (1.3.2) sha256=32fbbb0e53118ef42de20daa6ac94dbb758c628874092eba311b968a1e1d757b
msgpack (1.8.1) sha256=3fef787cd3965fd119c08a22724a56a93ca25008c3421fc15039f603a8b7c86c
msgpack (1.8.2) sha256=e440d11c99d6dfe8b2fbc4feb74c3518c1ba024357c70bbd734d9bb1a44d0d25
net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b
net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3
net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
@ -526,7 +526,7 @@ CHECKSUMS
rubocop (1.87.0) sha256=b9d9ddf55116a513f8ef2c7ae660662d8b49301f118d3f0df61865b33a5c188d
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
rubocop-rails (2.35.3) sha256=6edd45410866912b9b2e90ae3aeafd31d576df2bb2a9c9408f1667a50c32c7de
rubocop-rails (2.35.4) sha256=3aeaa325439c89950e8327565682ea794065d08e2ecbbfe95032bfa295a35df5
rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
ruby-vips (2.3.0) sha256=e685ec02c13969912debbd98019e50492e12989282da5f37d05f5471442f5374
@ -550,7 +550,7 @@ CHECKSUMS
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844
web-console (4.3.0) sha256=e13b71301cdfc2093f155b5aa3a622db80b4672d1f2f713119cc7ec7ac6a6da4
websocket-driver (0.8.0) sha256=ed0dba4b943c22f17f9a734817e808bc84cdce6a7e22045f5315aa57676d4962
websocket-driver (0.8.1) sha256=5ab238238ce230e5d4b262d2be39624c867914eab99171dc4952b58b577c2d96
websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241
zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12


+ 1
- 0
app/assets/images/ico-coins.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22"><path d="M14.5,7.25c-2.69,0-7.25.58-7.25,2.75v8.8c0,2.03,3.76,2.95,7.25,2.95s7.25-.92,7.25-2.95v-8.8c0-2.17-4.56-2.75-7.25-2.75ZM14.5,8.75c3.69,0,5.61.92,5.75,1.22-.14.36-2.07,1.28-5.75,1.28s-5.59-.91-5.75-1.21h0c.16-.38,2.08-1.29,5.75-1.29ZM8.75,11.78c1.57.73,4.04.97,5.75.97s4.18-.24,5.75-.97v2.69c-.16.37-2.08,1.28-5.75,1.28s-5.61-.92-5.75-1.25v-2.72ZM14.5,20.25c-3.77,0-5.75-1.08-5.75-1.45v-2.52c1.57.73,4.04.97,5.75.97s4.18-.24,5.75-.97v2.52c0,.37-1.98,1.45-5.75,1.45Z"/><path d="M1.75,7.83v-3.05c1.57.73,4.04.97,5.75.97s4.18-.24,5.75-.97v1.22h1.5v-3C14.75.83,10.19.25,7.5.25S.25.83.25,3v15c0,.08.01.15.03.23.54,1.72,3.73,2.52,5.72,2.52v-1.5c-1.89,0-3.91-.76-4.25-1.39v-3.11c1.25.68,2.99,1,4.25,1v-1.5c-1.91,0-3.95-.79-4.25-1.42v-3.08c1.25.68,2.99,1,4.25,1v-1.5c-1.91,0-3.95-.79-4.25-1.42ZM7.5,1.75c3.69,0,5.61.92,5.75,1.22-.14.36-2.07,1.28-5.75,1.28S1.91,3.34,1.75,3.04h0c.16-.38,2.08-1.29,5.75-1.29Z"/></svg>

+ 1
- 0
app/assets/images/ico-fuel.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" viewBox="0 0 20 22"><path d="M16.5,4.75h-4v-1.5h4v1.5ZM19.75,1v20c0,.41-.34.75-.75.75H1c-.41,0-.75-.34-.75-.75V5c0-.41.34-.75.75-.75h1.25v-1.75c0-.41.34-.75.75-.75h4c.41,0,.75.34.75.75v1.75h1.5V1c0-.41.34-.75.75-.75h9c.41,0,.75.34.75.75ZM3.75,4.25h2.5v-1h-2.5v1ZM18.25,1.75h-7.5v3.25c0,.41-.34.75-.75.75H1.75v14.5h16.5V1.75ZM10,8.47l.81.75c1.1,1.02,2.94,2.72,2.94,4.36,0,1.8-1.4,3.66-3.75,3.66s-3.75-1.86-3.75-3.66c0-1.65,1.84-3.35,2.95-4.36l.8-.75ZM10,10.52c-.85.79-2.25,2.16-2.25,3.06,0,1.06.84,2.16,2.25,2.16s2.25-1.1,2.25-2.16c0-.91-1.4-2.28-2.25-3.06Z"/></svg>

+ 1
- 0
app/assets/images/ico-thumb.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="19" viewBox="0 0 22 19"><path d="M21.48,8.88c-.07-.13-.16-.26-.25-.38-.83-1.04-2.24-1.04-5.05-1.04h-.4c-.44,0-.89,0-.99-.04-.05-.03-.09-.08-.1-.11,0-.11.12-.52.24-.91l.27-.86c.08-.25.12-.38.14-.49.29-1.18.1-2.41-.53-3.45-.07-.11-.14-.22-.29-.43-.11-.17-.17-.25-.23-.31-.64-.73-1.76-.8-2.5-.16-.06.05-.13.12-.26.27l-4.09,4.53c-1.02,1.13-1.58,1.75-1.88,2.54-.02.06-.04.13-.06.19-.66-.6-1.53-.97-2.49-.97-1.52,0-2.75,1.23-2.75,2.75v6c0,1.52,1.23,2.75,2.75,2.75,1.23,0,2.31-.6,2.99-1.51.11.16.23.3.37.44,1.11,1.07,2.64,1.07,5.7,1.07h.51c2.49,0,3.74,0,4.87-.65.11-.06.22-.13.32-.2,1.07-.73,1.59-1.85,2.62-4.07,1.17-2.51,1.75-3.77,1.1-4.95ZM5.25,15c0,1.24-1.01,2.25-2.25,2.25-.69,0-1.25-.56-1.25-1.25v-6c0-.69.56-1.25,1.25-1.25,1.24,0,2.25,1.01,2.25,2.25v4ZM19.02,13.21c-.92,1.97-1.38,2.96-2.11,3.46-.07.05-.14.09-.22.14-.78.45-1.9.45-4.12.45h-.51c-2.65,0-3.98,0-4.65-.65-.63-.61-.66-1.75-.66-4.48v-.97c0-1.36,0-2.04.21-2.58.21-.54.67-1.05,1.6-2.08L12.64,1.96c.07-.08.11-.12.14-.15.05-.04.12-.07.18-.07.08,0,.15.03.21.09.03.03.06.08.11.16.12.18.18.26.24.35.43.71.55,1.53.36,2.33-.02.1-.06.2-.12.4h0s-.27.87-.27.87c-.25.82-.39,1.27-.24,1.77.12.4.38.74.74.96.43.27.92.27,1.79.27h.4c2.18,0,3.49,0,3.88.48.04.05.08.11.11.17.28.51-.25,1.68-1.15,3.6Z"/></svg>

+ 186
- 1
app/assets/stylesheets/application.css View File

@ -123,6 +123,10 @@ body {
touch-action: manipulation;
background-color: var(--clr-white);
&:has(.results) {
background-color: var(--clr-sand-light);
}
}
.debug-score {
@ -132,6 +136,7 @@ body {
top: 0;
padding: 1rem;
background-color: var(--clr-white);
z-index: 100;
& dl {
display: grid;
@ -307,6 +312,12 @@ main {
}
}
.results {
--clr-action: var(--clr-green);
margin-block-end: 1rem;
}
.good_answer {
& .hero-container {
background-color: var(--clr-green);
@ -659,4 +670,178 @@ dialog::backdrop {
text-align: center;
flex: 1;
}
}
}
.results-header {
background-color: var(--clr-green);
padding: 2rem 1rem 3rem 1rem;
strong {
display: block;
}
}
.results-tagline {
display: grid;
grid-template-columns: 1fr max-content;
& svg {
fill: var(--clr-green);
rotate: 180deg;
}
&>div:first-child {
align-self: center;
font: var(--td-base);
padding: 1rem 0 1rem 1rem;
}
}
.impact {
display: flex;
flex-direction: column;
margin: 1.5rem 1rem;
font: var(--td-base);
& + .impact {
margin-block-start: 0;
}
& h3 {
font: var(--td-base);
font-weight: 700;
margin: 0;
}
& .icon {
width: 40px;
aspect-ratio: 1;
display: inline-flex;
justify-content: center;
align-items: center;
background-color: var(--clr-green);
border-radius: 50%;
margin-block-end: 0.25rem;
}
& details {
border-width: 1px 0;
border-color: var(--clr-black);
border-style: solid;
margin: 0.5rem 0;
padding: 0.5rem 0;
& summary {
list-style: none;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
}
h4 {
font: var(--td-base);
font-weight: 700;
margin: 0;
}
& p {
margin: 0.5rem 0;
}
& summary::-webkit-details-marker { display: none; }
& .details-icon {
width: 23px;
aspect-ratio: 1;
border-radius: 50%;
border: 1px solid var(--clr-black);
box-sizing: border-box;
position: relative;
&::before {
content: "";
height: 13px;
width: 1px;
left: 10px;
top: 4px;
position: absolute;
background-color: var(--clr-black);
}
&::after {
content: "";
width: 13px;
height: 1px;
left: 4px;
top: 10px;
position: absolute;
background-color: var(--clr-black);
}
}
&[open] .details-icon::before {
display: none;
}
}
}
.like-container {
margin: 0 1rem 1.5rem 1rem;
& h3 {
font: var(--td-base);
font-weight: 700;
margin: 0 0 0.5rem 0;
}
& > div {
display: flex;
gap: 0.5rem;
}
button {
appearance: none;
border-radius: 50%;
width: 40px;
aspect-ratio: 1;
border: 1px solid var(--clr-black);
background-color: transparent;
display: flex;
justify-content: center;
align-items: center;
&.thumbs-down {
& svg {
rotate: 180deg;
}
}
}
}
.newsletter-container {
margin: 0 1rem 2rem 1rem;
& p {
margin: 0 0 1rem 0;
}
a {
display: inline-flex;
align-items: center;
gap: 0.5rem;
color: var(--clr-black);
text-decoration: none;
& span:has(svg) {
background-color: var(--clr-green);
width: 32px;
height: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
}
}

+ 5
- 3
app/controllers/game_controller.rb View File

@ -65,7 +65,6 @@ class GameController < ApplicationController
def last_save
@node = last_save_node
end
@ -83,6 +82,8 @@ class GameController < ApplicationController
def done
current_player.update(is_done: true) unless current_player.is_done?
if current_player.last_save_answer_id
@node = last_save_node
@result_node = @node.descendants.find_by(id: current_player.last_save_answer_id)
@ -93,7 +94,8 @@ class GameController < ApplicationController
end
def result
def results
@node = root_node.children.results.first
end
@ -110,7 +112,7 @@ private
def stages
@stages ||= root_node.children.stage
@stages ||= root_node.children.ordered.stage
end


+ 63
- 0
app/helpers/game_helper.rb View File

@ -42,4 +42,67 @@ module GameHelper
"#{rails_storage_proxy_path(asset.file.variant(resize_to_limit: [ w, nil ], format: "webp"))} #{w}w"
}.join(", ")
end
RESULT_BANDS = [ [ 8, :best ], [ 5, :balanced ], [ 0, :worst ] ].freeze
def result_state(player)
if (answer_id = player.last_save_answer_id)
return last_save_result_state(answer_id)
end
overall = player.score.to_i
RESULT_BANDS.find { |threshold, _| overall >= threshold }.last
end
def result_headline(player)
t("game.results.#{result_state(player)}.headline").html_safe
end
def result_description(player)
t("game.results.#{result_state(player)}.description").html_safe
end
IMPACT_TONE_BANDS = {
default: [ [ 3, :positive ], [ 1, :neutral ], [ -Float::INFINITY, :negative ] ],
income: [ [ 2, :positive ], [ 0, :neutral ], [ -Float::INFINITY, :negative ] ]
}.freeze
def impact_tone(player, category)
score = player.score_for(category)
bands = IMPACT_TONE_BANDS[category] || IMPACT_TONE_BANDS[:default]
bands.find { |threshold, _| score >= threshold }.last
end
def impact_label(category)
t("game.results.#{category}.label")
end
def impact_message(player, category)
if category == :income && player.last_save_answer_id.present?
return t("game.results.income.early_exit")
end
t("game.results.#{category}.#{impact_tone(player, category)}")
end
def impact_learn_more(category)
t("game.results.#{category}.learn_more")
end
private
def last_save_result_state(answer_id)
answer = Node.find_by(id: answer_id)
config = JSON.parse(Rails.root.join("config", "question_scores.json").read)
type = config.dig("last_save", "answers", answer.position - 1, "result_type") if answer
type&.to_sym || :compost
end
end

+ 3
- 2
app/models/node.rb View File

@ -31,7 +31,8 @@ class Node < ApplicationRecord
good_answer: 4,
bad_answer: 5,
chance: 6,
last_save: 7
last_save: 7,
results: 8
}
def available_templates
@ -39,7 +40,7 @@ class Node < ApplicationRecord
case depth
when 1
[ :facts, :intro, :stage, :last_save ]
[ :facts, :intro, :stage, :last_save, :results ]
when 2
[ :good_answer, :bad_answer, :chance ]
when 3


+ 1
- 1
app/views/game/done.html.erb View File

@ -16,7 +16,7 @@
<div>
<%= link_to tag.span(t("game.drumroll_see_the_result")),
{ action: "result" },
{ action: "results" },
class: (@result_node.parent.chance? and @result_node.bad_answer?) ? "cta last_save" : "cta" %>
</div>
</article>


+ 0
- 1
app/views/game/result.html.erb View File

@ -1 +0,0 @@
<%- content_for :title, node_title(@node) %>

+ 84
- 0
app/views/game/results.html.erb View File

@ -0,0 +1,84 @@
<%- content_for :title, node_title(@node) %>
<div class="results-header">
<h1><%= result_headline(current_player) %></h1>
</div>
<div class="results-tagline">
<div>
<div><%= result_description(current_player) %></div>
</div>
<%= svg "ico-wave" %>
</div>
<div class="impact food-waste">
<div class="icon"><%= svg "ico-last-save" %></div>
<h3><%= impact_label(:food_waste) %></h3>
<p><%= impact_message(current_player, :food_waste) %></p>
<details class="impact-learn-more">
<summary>
<h4><%= t("game.results.what_many_dont_know") %></h4>
<span class="details-icon"></span>
</summary>
<% impact_learn_more(:food_waste).each do |paragraph| %>
<p><%= paragraph %></p>
<% end %>
</details>
</div>
<div class="impact emissions">
<div class="icon"><%= svg "ico-fuel" %></div>
<h3><%= impact_label(:emissions) %></h3>
<p><%= impact_message(current_player, :emissions) %></p>
<details class="impact-learn-more">
<summary>
<h4><%= t("game.results.what_many_dont_know") %></h4>
<span class="details-icon"></span>
</summary>
<% impact_learn_more(:emissions).each do |paragraph| %>
<p><%= paragraph %></p>
<% end %>
</details>
</div>
<div class="impact income">
<div class="icon"><%= svg "ico-coins" %></div>
<h3><%= impact_label(:income) %></h3>
<p><%= impact_message(current_player, :income) %></p>
<details class="impact-learn-more">
<summary>
<h4><%= t("game.results.what_many_dont_know") %></h4>
<span class="details-icon"></span>
</summary>
<% impact_learn_more(:income).each do |paragraph| %>
<p><%= paragraph %></p>
<% end %>
</details>
</div>
<div class="like-container">
<%= tag.h3 t("game.did_you_like_this_game") %>
<div>
<button class="thumbs-up"><%= svg "ico-thumb" %></button>
<button class="thumbs-down"><%= svg "ico-thumb" %></button>
</div>
</div>
<div class="newsletter-container">
<%= tag.h3 t("game.join_our_newsletter") %>
<%= tag.p t("game.join_our_newsletter_desc") %>
<%= link_to "#" do %>
<%= tag.span svg("ico-arrow-right") %>
<%= tag.span t("game.sounds_good") %>
<% end %>
</div>
<%= button_to tag.span(t("game.save_another_tomato")), start_path, class: "cta" %>

+ 53
- 2
config/locales/en.yml View File

@ -15,11 +15,11 @@ en:
play_time: Play time 2-5 minutes
go_to_slide: Go to slide
got_it_lets_get_started: Got it, let’s get started
got_it_lets_get_started: Got it, let’s get started
stage_i_of_n: Stage %{i} of %{n}
take_a_chance: Take a chance
its_risky: |
its_risky: |
<strong>It’s risky</strong><br>
but it can boost your score.
ok: Ok
@ -27,6 +27,56 @@ en:
next_stage: Next stage
let_me_try: Let me try
drumroll_see_the_result: Drumroll… see your result
did_you_like_this_game: Did you like this game?
join_our_newsletter: Join our newsletter
join_our_newsletter_desc: We'd love to keep you in the loop and share stories about our partners and the important work they're doing.
sounds_good: Sounds good!
save_another_tomato: Save another tomato
results:
best:
headline: <strong>Well done!</strong> You saved the tomato!
description: "That was just excellent. Let’s take a closer look at some of your moves:"
balanced:
headline: <strong>Good job!</strong> You saved the tomato!
description: "Overall, you did well. Let’s take a closer look at some of your moves:"
worst:
headline: <strong>Phew!</strong> You saved the tomato!
description: "But it was a close call. Let’s take a closer look at some of your moves:"
compost:
headline: <strong>Good save!</strong> Your tomato ended up as compost!
description: "Let’s take a closer look at some of your moves:"
landfill:
headline: <strong>Ouch!</strong> Your tomato ended up in a landfill!
description: "Let’s take a closer look at some of your moves:"
what_many_dont_know: What many don’t know
food_waste:
label: Food Waste
positive: Your choices helped prevent food waste and kept the tomato useful for longer.
neutral: Some choices helped reduce food waste, while others still created risks.
negative: Some choices increased the risk of the tomato going to waste.
learn_more:
- Fresh produce, like tomatoes, can go to waste while it grows. But the risk of food waste is also big after harvest, for example during storage and transport.
- Here, even simple solutions like stackable crates can help reduce food waste, because you avoid the food getting squashed and damaged on its way to the market. Solar-powered cooling solutions can also help, as they can prevent food from spoiling in the heat.
emissions:
label: Emissions
positive: Your choices helped reduce greenhouse gas emissions.
neutral: Some choices lowered emissions, while others still added climate impact.
negative: Some choices increased greenhouse gas emissions.
learn_more:
- Food waste itself can cause greenhouse gases when it rots in a landfill. That’s why it’s key to avoid food waste in the first place. When food spoils or isn’t safe to eat, composting it is a more climate-friendly option. Maybe you’re already doing this at home or in your local community!
- Greenhouse gases can also come from using things like chemical fertiliser, as well as pumps, vans, and trucks that run on diesel and gasoline. So, ensuring farmers have access to renewable energy, electric transport and training in eco-friendly farming can also help lower emissions a lot.
income:
label: Income
positive: Your choices helped farmers earn more from their crops.
neutral: Some choices improved income opportunities, but not all decisions supported farmers.
negative: Some choices made it harder for farmers to earn income from the tomato.
early_exit: You didn’t get to sell your tomato.
learn_more:
- Finding a place to sell the things you grow isn’t always easy for small farmers. Setting up produce hubs can help, because then farmers can get together, bulk their crops and sell at a better price. Helping farmers connect with local shops and supermarkets is also a good solution. That means shorter travel distances and a lower risk of food waste and pollution.
- Another thing to keep in mind is that small farmers’ incomes are affected by a lot of things. Money for fertiliser and water is not always available, which can make it harder to grow crops and earn money. That’s why access to a small business loan can help.
countries:
au: Australia
@ -290,6 +340,7 @@ en:
bad_answer: Bad answer
chance: Chance
last_save: Last save
results: Score
categories:
box: Box


+ 1
- 1
config/routes.rb View File

@ -74,7 +74,7 @@ Rails.application.routes.draw do
post "last_save/answer", to: "game#answer_last_save"
get "done", to: "game#done"
get "result", to: "game#result"
get "results", to: "game#results"
get "", to: "game#index", as: :locale_root
end


Loading…
Cancel
Save