From 5f225d8cb6878edc0f6ad651baf5af9ea79693da Mon Sep 17 00:00:00 2001 From: Charley DAVID Date: Wed, 31 May 2017 19:20:49 -0300 Subject: [PATCH] Add prices page --- app/helpers/prices_helper.rb | 23 ++++++++ app/views/games/index.slim | 71 +++++++++++++++++-------- app/views/layouts/application.html.slim | 60 +++++++++++++++++++-- app/views/prices/index.slim | 39 ++++++++++++++ 4 files changed, 166 insertions(+), 27 deletions(-) create mode 100644 app/helpers/prices_helper.rb create mode 100644 app/views/prices/index.slim diff --git a/app/helpers/prices_helper.rb b/app/helpers/prices_helper.rb new file mode 100644 index 0000000..59fad3a --- /dev/null +++ b/app/helpers/prices_helper.rb @@ -0,0 +1,23 @@ +module PricesHelper + def prices_by_country(games: [], countries:, currency: nil) + prices = games.flat_map(&:prices) + cache = prices.each_with_object({}) do |price, result| + result[price.country] = price.value.exchange_to(currency || 'USD') + end + min, max = cache.values.minmax + + countries.each do |country| + price = prices.detect { |p| p.country == country } + title = "\"#{games.first.title}\" price in #{ISO3166::Country[country].translation('en')}" + if price + options = { + class: (min == cache[country] && 'table-success') || (max == cache[country] && 'table-danger'), + title: title, + } + yield(price.value.exchange_to(currency || price.currency).format, options) + else + yield('N/A', { class: 'text-muted', title: title }) + end + end + end +end diff --git a/app/views/games/index.slim b/app/views/games/index.slim index fecb045..dd546eb 100644 --- a/app/views/games/index.slim +++ b/app/views/games/index.slim @@ -1,23 +1,48 @@ -table.table.table-responsive - thead.thead-default - tr - th Cover - th Code - th Region - th style="width:100%;min-width:200px" Title - th eShop ID (nsuid) - th Release date - tbody.games - - @games.each do |region, games| - - cover = games.map(&:cover_url).compact.first - - games.each_with_index do |game, index| - tr.game - - if index.zero? - td.game--cover-url rowspan=games.count - = cover ? image_tag("https://assets.calyh.re/resize?url=#{cover}", style: 'max-width:120px;max-height:120px;', class: 'rounded mx-auto d-block', title: 'wat') : nil - td.game--code rowspan=games.count = game.game_code - td.game--region = game.region - td.game--title.text-overflow style="width:100%;max-width:0" title=games.first.title = game.title - td.game--nsuid = game.nsuid || 'NA' - td.game--release-date - time.text-overflow datetime=game.release_date.iso8601 = game.release_date.strftime("%b #{game.release_date.day.ordinalize}, %Y") +- content_for :head_style do + css: + .games { + min-width: 800px; + } + .game-cover { + width: 144px; + } + .game-code { + width: 70px; + } + .game-region { + width: 100px; + } + .game-title { + width: 100%; + } + .game-nsuid { + width: 170px; + } + .game-release-date { + width: 140px; + } + +.scroll-container + table.table + thead.thead-default + tr + th.game-cover Cover + th.game-code Code + th.game-region Region + th.game-title Title + th.game-nsuid eShop ID (nsuid) + th.game-release-date Release date + tbody.games + - @games.each do |region, games| + - cover = games.map(&:cover_url).compact.first + - games.each_with_index do |game, index| + tr.game + - if index.zero? + td.game-cover rowspan=games.count + = cover ? image_tag("https://assets.calyh.re/resize?url=#{cover}", style: 'max-width:120px;max-height:120px;', class: 'rounded mx-auto d-block', title: 'wat') : nil + td.game-code rowspan=games.count = game.game_code + td.game-region = game.region + td.game-title.text-overflow title=games.first.title = game.title + td.game-nsuid.text-overflow title=game.nsuid = game.nsuid || 'NA' + td.game-release-date.text-overflow title=game.release_date.iso8601 + time.text-overflow datetime=game.release_date.iso8601 = game.release_date.strftime("%b #{game.release_date.day.ordinalize}, %Y") diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index 57558a6..fdcf4f4 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -11,6 +11,21 @@ html script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous" css: + html, body { + width: 100%; + height: 100%; + } + table { + } + .navbar + .scroll-container { + height: calc(100% - 62px); + } + .scroll-container { + position: relative; + display: block; + width: 100%; + overflow: scroll; + } .text-overflow { white-space: nowrap; overflow: hidden; @@ -19,6 +34,43 @@ html .text-muted { opacity: .2; } + .text-centered { + display: inline-flex; + align-items: center; + justify-content: center; + margin: auto; + } + .emoji { + display: block; + margin-left: 8px; + margin-right: 8px; + } + + thead { + position: sticky; + z-index: 2; + top: 0; + } + + thead, tbody { + display: table; + table-layout: fixed; + width: 100%; + } + + .column--frozen { + position: sticky; + z-index: 1; + left: 0; + width: 200px; + min-width: 200px; + max-width: 200px; + background-color: #FFF; + box-shadow: inset -1px 0 0 0 #eceeef; + font-weight: bold; + } + + = content_for :head_style body nav.navbar.navbar-toggleable-sm.navbar-light.bg-faded.sticky-top style="width: 100%" @@ -30,10 +82,10 @@ html #navbarSupportedContent.navbar-collapse.collapse ul.navbar-nav.mr-auto - li.nav-item class=(@current_page == 'games' ? 'active' : nil) - = link_to 'Game list', games_url, class: 'nav-link' - li.nav-item class=(@current_page == 'prices' ? 'active' : nil) - = link_to 'All prices', prices_url, class: 'nav-link' + li.nav-item class=(current_page?(controller: :prices) ? 'active' : nil) + = link_to 'Prices', prices_url, class: 'nav-link' + li.nav-item class=(current_page?(controller: :games) ? 'active' : nil) + = link_to 'Games', games_url, class: 'nav-link' = content_for :navbar_right diff --git a/app/views/prices/index.slim b/app/views/prices/index.slim new file mode 100644 index 0000000..a1b6e10 --- /dev/null +++ b/app/views/prices/index.slim @@ -0,0 +1,39 @@ +- content_for :head_style do + css: + td { + font-size: 0.9rem; + } + +- content_for :navbar_right do + ul.navbar-nav + li.nav-item.dropdown + = link_to '#', class: 'nav-link dropdown-toggle', id: 'navbarDropdownMenuLink', data: { toggle: 'dropdown' }, aria: { haspopup: true, expanded: false } do + - if @currency.nil? + | Change currency + - else + = ISO3166::Country.find_country_by_currency(@currency).currency.name + .dropdown-menu.dropdown-menu-right aria-labelledby="navbarDropdownMenuLink" + - unless @currency.nil? + = link_to 'In original currency', prices_url, class: 'dropdown-item' + .dropdown-divider + - @currencies.each do |currency| + - next if @currency === currency + = link_to ISO3166::Country.find_country_by_currency(currency).currency.name, prices_url(currency: currency), class: 'dropdown-item' + +.scroll-container + table.table.table-hover + thead.thead-default + tr + th.column--frozen Game + - @countries.each do |code| + - country = ISO3166::Country[code] + th.game-country.text-right style="width: 110px" title=country.unofficial_names.first + .text-centered + span.emoji = country.emoji_flag + = country.alpha3 + tbody.games + - @games.each do |region, games| + tr.game title=games.first.title + td.game-title.column--frozen.text-overflow = games.first.title + - prices_by_country(games: games, countries: @countries, currency: @currency) do |price, options| + td.text-overflow.text-right style="width: 110px" title=options[:title] class=options[:class] = price