diff --git a/app.rb b/app.rb index b6f71e7..13fbc78 100644 --- a/app.rb +++ b/app.rb @@ -6,6 +6,7 @@ require 'tilt/sass' require 'active_support/core_ext' require 'open-uri' +require 'json' require 'csv' $LOAD_PATH << File.expand_path('../lib', __FILE__) @@ -167,6 +168,16 @@ erb :term end +get '/reports/:country' do + redirect to('/login') unless current_user + @country = Everypolitician.country(slug: params[:country]) + stats_raw = JSON.parse(open('https://everypolitician.github.io/gender-balance-country-stats/stats.json').read, symbolize_names: true) + stats = Hash[stats_raw.map { |c| [c[:slug], c] }] + @country_stats = stats[params[:country]] + @legislature_stats = Hash[@country_stats[:legislatures].map {|l| [l[:slug], l]}] + erb :report, :layout => :layout_page +end + get '/_stats' do @players = Vote.join(:users, id: :user_id).group_and_count(:users__id) erb :stats diff --git a/public/js/main.js b/public/js/main.js index ed0562a..0fce36c 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -316,4 +316,57 @@ $(function(){ ga('send', 'event', 'filterElements', 'focus', label); }); + $('[data-scroll-to-id]').on('click', function(e){ + e.preventDefault(); + + if( this.hasAttribute('href') ){ + var $target = $($(this).attr('href')); + } else { + var $target = $('#' + $(this).attr('data-scroll-to-id')); + } + + $('html, body').animate({ + scrollTop: $target.offset().top + }, 250); + }); + + // Prototypes that should be replaced eventually with real code. + $('[data-display-by-term]').on('click', function(){ + var $report = $(this).parents('.report'); + var $reportList = $(this).parents('.report-list'); + id = '#terms-' + $report.attr('id'); + var $terms = $(this).parents('.page-section').find(id); + + var wasAlreadyOpen = $report.next('.report-list--child').length; + + $reportList.find('.report-list--child').slideUp(100, function(){ + $(this).remove(); + }); + + if( ! wasAlreadyOpen ){ + var $clone = $terms.clone().addClass('report-list--child').removeClass('report-list--hidden'); + $clone.find('.report__action').remove(); + $clone.hide().insertAfter($report).slideDown(100); + } + }); + + $('[data-display-by-group]').on('click', function(){ + var $report = $(this).parents('.report'); + var $reportList = $(this).parents('.report-list'); + id = '#parties-' + $report.attr('id'); + var $groups = $(this).parents('.page-section').find(id); + + var wasAlreadyOpen = $report.next('.report-list--child').length; + + $reportList.find('.report-list--child').slideUp(100, function(){ + $(this).remove(); + }); + + if( ! wasAlreadyOpen ){ + var $clone = $groups.clone().addClass('report-list--child').removeClass('report-list--hidden'); + $clone.find('.report__action').remove(); + $clone.hide().insertAfter($report).slideDown(100); + } + }); + }); diff --git a/views/layout_page.erb b/views/layout_page.erb new file mode 100644 index 0000000..1f0925f --- /dev/null +++ b/views/layout_page.erb @@ -0,0 +1,60 @@ + + + + + + + Gender Balance + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ <%= erb :flash %> +
+ +
+ <%= yield %> +
+ + diff --git a/views/report.erb b/views/report.erb new file mode 100644 index 0000000..1df149b --- /dev/null +++ b/views/report.erb @@ -0,0 +1,136 @@ +<% content_for :body_class do %>report-page<% end %> + +<% content_for :back_button do %> + Countries +<% end %> + +
+
+ + <% unless params[:nobanner] %> + + <% end %> + +

<%= @country[:country] %>

+ +

+ " class="button button--small">Play this country! + Download data +

+ +
+ <% @country.legislatures.each_slice(2) do |legislatures| %> +
+ <% legislatures.each do |legislature| %> + <% + stats = @legislature_stats[legislature.slug][:totals] + total = stats[:overall][:total].to_f + male = stats[:overall][:male].to_f + female = stats[:overall][:female].to_f + total = male + female + %> + + <% end %> +
+ <% end %> +
+
+
+ +<% @country.legislatures.each do |legislature| %> +
+
+ +

<%= legislature.name %>

+ +
+
+

Gender balance by term:

+
+ <% legislature.legislative_periods.each do |term| %> + <% term_slug = 'term/' + term.slug + term_stats = @legislature_stats[legislature.slug][:terms][term_slug.to_sym] %> + <%= erb :report_partial, locals: { + report: { + id: term.slug, + title: term.name, + total: term_stats[:overall][:total].to_f, + total_male: term_stats[:overall][:male].to_f, + total_female: term_stats[:overall][:female].to_f, + action: 'display-by-group' + } + } %> +
+ <% term_stats[:parties].each do |slug, group| %> + <%= erb :report_partial, locals: { + report: { + title: group[:name], + total: group[:total].to_f, + total_male: group[:male].to_f, + total_female: group[:female].to_f, + } + } %> + <% end %> +
+ <% end %> +
+
+
+

Gender balance by group:

+ <% stats = @legislature_stats[legislature.slug][:totals] %> +
+ <% stats[:parties].each do |slug, data| + id_slug = slug.to_s.sub('/', '-') %> + <%= erb :report_partial, locals: { + report: { + id: id_slug, + title: data[:name], + total: data[:total].to_f, + total_male: data[:male].to_f, + total_female: data[:female].to_f, + action: 'display-by-term' + } + } %> +
+ <% legislature.legislative_periods.each do |term| + term_slug = 'term/' + term.slug + term_stats = @legislature_stats[legislature.slug][:terms][term_slug.to_sym] + group = term_stats[:parties][slug] + if group %> + <%= erb :report_partial, locals: { + report: { + title: term[:name], + total: group[:total].to_f, + total_male: group[:male].to_f, + total_female: group[:female].to_f, + } + } %> + <% end %> + <% end %> +
+ <% end %> +
+
+
+
+
+<% end %> diff --git a/views/report_partial.erb b/views/report_partial.erb new file mode 100644 index 0000000..00dc5ef --- /dev/null +++ b/views/report_partial.erb @@ -0,0 +1,25 @@ +
+ +

<%= report[:title] %>

+ + <% if report[:action] == 'display-by-group' %> + Display by group + <% elsif report[:action] == 'display-by-term' %> + Display by term + <% end %> + +
+
+ <%= report[:total_male].to_i %> <%= report[:total_male].to_i == 1 ? 'man' : 'men' %> +
+ <% if (report[:total_male] + report[:total_female] != report[:total]) %> +
+
+ <% end %> +
+ <%= report[:total_female].to_i %> <%= report[:total_female].to_i == 1 ? 'woman' : 'women' %> +
+
+ +
+ diff --git a/views/sass/_components.scss b/views/sass/_components.scss index 184f208..a3bd9e1 100644 --- a/views/sass/_components.scss +++ b/views/sass/_components.scss @@ -230,6 +230,10 @@ background-color: $color_red; } +.progress-bar__empty { + background-color: transparent; +} + .progress-bar--gendered { .progress-bar__males { background-color: $color_orange; diff --git a/views/sass/_grid.scss b/views/sass/_grid.scss new file mode 100644 index 0000000..878c3fd --- /dev/null +++ b/views/sass/_grid.scss @@ -0,0 +1,42 @@ +$grid-max-width: 960px !default; +$grid-gutter: 2em !default; +$grid-breakpoint-sm: 768px !default; + +.container { + margin-right: auto; + margin-left: auto; + padding-left: $grid-gutter / 2; + padding-right: $grid-gutter / 2; + max-width: $grid-max-width; +} + +.row { + @include clearfix(); + margin-left: $grid-gutter / -2; + margin-right: $grid-gutter / -2; +} + +%col { + padding-left: $grid-gutter / 2; + padding-right: $grid-gutter / 2; + min-height: 1px; +} + +@for $i from 1 through 12 { + .col-sm-#{$i} { + @extend %col; + } +} + +@media(min-width: $grid-breakpoint-sm) { + %col-float { + float: left; + } + + @for $i from 1 through 12 { + .col-sm-#{$i} { + @extend %col-float; + width: 100% / 12 * $i; + } + } +} diff --git a/views/sass/_messages.scss b/views/sass/_messages.scss index dd5cfa4..1d25f14 100644 --- a/views/sass/_messages.scss +++ b/views/sass/_messages.scss @@ -8,21 +8,21 @@ transform: translate(0,-120%); @include vendor-prefix(transition, transform 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275)); - .alert { - padding: 0.7em 1em; - margin-top: 1em; - background: $color_light_yellow; - text-align: center; - border-radius: $border_radius; - box-shadow: 0.3em 0.3em 0 rgba(0,0,0,0.05); - } - - .alert--danger { - background: $color_light_red; - color: mix($color_dark_red, #000, 50%); - } - &.slide-in { transform: translate(0,0); } -} \ No newline at end of file +} + +.alert { + padding: 0.7em 1em; + margin-top: 1em; + background: $color_light_yellow; + text-align: center; + border-radius: $border_radius; + box-shadow: 0.3em 0.3em 0 rgba(0,0,0,0.05); +} + +.alert--danger { + background: $color_light_red; + color: mix($color_dark_red, #000, 50%); +} diff --git a/views/sass/_page.scss b/views/sass/_page.scss new file mode 100644 index 0000000..807a590 --- /dev/null +++ b/views/sass/_page.scss @@ -0,0 +1,71 @@ +// Most of gender-balance is focussed around "app-like" screens with a +// minimal header and tight gutters. But the rest of the site is made +// from mostly static "page" type pages. These styles are for them. + +body.page { + padding-top: 0; +} + +.page-header { + text-align: center; + padding: 0.5em 0; + background-color: $color_white; + position: relative; + + @media (min-width: $screen_medium_min) { + padding: 1em 0; + } + + .container { + position: relative; + } + + a, h1 { + line-height: 1.1em; + font-size: 1em; + margin: 0; + } +} + +.page-header__back { + position: absolute; + text-decoration: none; + font-size: 0.9em; + padding: 0.5em; + + left: 0; + top: -0.5em; // vertically centre in header + + @media (min-width: $screen_medium_min) { + font-size: 1em; + left: 0.5em; + } + + .fa { + vertical-align: middle; + } +} + +.page-section { + padding: 1em 0; + + @media (min-width: $screen_medium_min) and (min-height: 700px) { + padding: 2em 0; + } + + .container { + @include remove-margin-from-children(); + } +} + +.page-section--white { + background-color: $color_white; + + & + & { + border-top: 1px solid $color_off_white; + } +} + +.page-section--blue { + background-color: $color_off_white; +} diff --git a/views/sass/_report.scss b/views/sass/_report.scss new file mode 100644 index 0000000..80e45cf --- /dev/null +++ b/views/sass/_report.scss @@ -0,0 +1,70 @@ +.report-actions { + text-align: center; + + .button { + background: #fff; + } + + .button + .button { + margin-left: 1em; + } +} + +.report-legislatures { + .list__item { + margin-top: 1em; + } +} + +.report-list--child { + padding-left: 2em; + font-size: 0.9em; + margin-bottom: 2em; + + .progress-bar, + .progress-bar > * { + height: 0.4em; + } +} + +.report-list--hidden { + display: none; +} + +.report { + padding-bottom: 1px; // force .report to wrap around .progress-bar's bottom margin + margin-bottom: 1em; + + .progress-bar { + clear: both; + } +} + +.report__title { + float: left; + margin: 0; + font-size: 0.9em; + padding-bottom: 0.5em * (1 / 0.9); + font-weight: normal; +} + +.report__action { + float: right; + margin: 0; + font-size: 0.8em; + padding-bottom: 0.5em * (1 / 0.8); + + cursor: pointer; +} + +.report-blank-slate { + padding: 1.5em; + font-size: 0.8em; + line-height: 1.4em; + + background-color: $color_off_white; + color: $color_mid_grey; + border-radius: $border_radius; + + @include remove-margin-from-children(); +} \ No newline at end of file diff --git a/views/sass/_variables.scss b/views/sass/_variables.scss index 4952f14..46740a7 100644 --- a/views/sass/_variables.scss +++ b/views/sass/_variables.scss @@ -49,3 +49,6 @@ $screen_large_max: $screen_xlarge_min - $one_pixel_in_root_ems; $screen_xlarge_max: $screen_huge_min - $one_pixel_in_root_ems; $high_dpi_screen: '-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi'; + +$grid-gutter: 4em; +$grid-breakpoint-sm: $screen_medium_min; diff --git a/views/sass/main.scss b/views/sass/main.scss index 5342958..d0187ee 100644 --- a/views/sass/main.scss +++ b/views/sass/main.scss @@ -51,6 +51,7 @@ body { } } +@import 'grid'; @import 'typography'; @import 'components'; @import 'header'; @@ -59,3 +60,5 @@ body { @import 'messages'; @import 'countries'; @import 'person'; +@import 'page'; +@import 'report';