spree_frontend 4.2.0.rc5 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree/frontend.js +10 -0
  3. data/app/assets/javascripts/spree/frontend/account.js +1 -1
  4. data/app/assets/javascripts/spree/frontend/cart.js +1 -1
  5. data/app/assets/javascripts/spree/frontend/checkout/address.js +1 -1
  6. data/app/assets/javascripts/spree/frontend/coupon_manager.js +2 -2
  7. data/app/assets/javascripts/spree/frontend/currency.js +11 -0
  8. data/app/assets/javascripts/spree/frontend/locale.js +11 -0
  9. data/app/assets/stylesheets/spree/frontend/application.scss +0 -3
  10. data/app/assets/stylesheets/spree/frontend/variables/bootstrap-overrides.scss +1 -0
  11. data/app/assets/stylesheets/spree/frontend/variables/helper-variables.scss +1 -0
  12. data/app/assets/stylesheets/spree/frontend/variables/variables.scss +54 -0
  13. data/app/controllers/concerns/spree/locale_urls.rb +23 -0
  14. data/app/controllers/spree/checkout_controller.rb +8 -8
  15. data/app/controllers/spree/currency_controller.rb +6 -10
  16. data/app/controllers/spree/locale_controller.rb +23 -6
  17. data/app/controllers/spree/orders_controller.rb +2 -2
  18. data/app/controllers/spree/store_controller.rb +8 -2
  19. data/app/helpers/spree/addresses_helper.rb +9 -2
  20. data/app/helpers/spree/frontend_helper.rb +6 -20
  21. data/app/helpers/spree/navigation_helper.rb +6 -1
  22. data/app/helpers/spree/store_helper.rb +39 -0
  23. data/app/helpers/spree/taxons_helper.rb +1 -1
  24. data/app/views/spree/checkout/_address.html.erb +2 -4
  25. data/app/views/spree/locale/index.html.erb +1 -0
  26. data/app/views/spree/orders/_line_item.html.erb +1 -1
  27. data/app/views/spree/products/_color_option_type.html.erb +1 -1
  28. data/app/views/spree/shared/_currency_dropdown.html.erb +13 -0
  29. data/app/views/spree/shared/_footer.html.erb +1 -1
  30. data/app/views/spree/shared/_head.html.erb +4 -0
  31. data/app/views/spree/shared/_internationalization_options.html.erb +31 -0
  32. data/app/views/spree/shared/_line_item.html.erb +2 -2
  33. data/app/views/spree/shared/_link_to_account.html.erb +5 -5
  34. data/app/views/spree/shared/_locale_dropdown.html.erb +13 -0
  35. data/app/views/spree/shared/_login.html.erb +1 -1
  36. data/app/views/spree/shared/_mobile_internationalization_options.html.erb +37 -0
  37. data/app/views/spree/shared/_mobile_navigation.html.erb +2 -5
  38. data/app/views/spree/shared/_nav_bar.html.erb +1 -1
  39. data/app/views/spree/shared/_order_details.html.erb +2 -2
  40. data/app/views/spree/users/show.html.erb +1 -1
  41. data/config/routes.rb +26 -29
  42. data/lib/generators/spree/frontend/copy_storefront/copy_storefront_generator.rb +1 -7
  43. data/lib/generators/spree/frontend/install/install_generator.rb +34 -0
  44. data/lib/generators/spree/frontend/install/templates/config/initializers/spree_storefront.rb +1 -0
  45. data/lib/generators/spree/frontend/install/templates/config/spree_storefront.yml +99 -0
  46. metadata +22 -12
  47. data/app/views/spree/shared/_change_store.html.erb +0 -25
  48. data/app/views/spree/shared/_mobile_change_store.html.erb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c687a751a5affd4522bc602689a69466af4401bcda69b405b419dda929e737d
4
- data.tar.gz: c8e4dbc7e128ab9d655ba9afdb60891d700224a9a5a8e62ab1f7d9720b30a9b2
3
+ metadata.gz: b202f99393b22f252f8c79ce9dbb68bdb3886df0095db558b7aeb54649d7442a
4
+ data.tar.gz: b6bf3f9b0dff2c97e90773fe58113d589711bb830ce921211b447b73b1a24631
5
5
  SHA512:
6
- metadata.gz: 238f9fb68b0c36b60aee012683d1d33854fc1c9ed28fefc94e080fb194974b8a75d9c91b2634be22b98efac96cf136a4a34228658844aec166d117c1d0d062d1
7
- data.tar.gz: c34ae40194f58f11d2dfdf1b8f89dc57c61b84e97cc2a13b18e1f8670ce841e0c9d2e87d65e780936912bd2ef478d933de50e019830332bc57ec53bfffa46ede
6
+ metadata.gz: 6ca9c497131e513e80a043e7dae75e7e3dacff782fc0d4111fa1c4883c68db5db58f351a734065accb375855cb3e05ec3d080453777865cf5a51d81507fa103a
7
+ data.tar.gz: 459e4adc0b271ee193f9e99c7bec8b044d45ffc94449e897fcdc8ca1d1a2c696f13bc7adda5be001e59eaf5f3fdd07647c8a6b45890b1539990a5633393205da
@@ -15,6 +15,8 @@
15
15
  //= require spree/frontend/api_tokens
16
16
  //= require spree/frontend/carousel-noconflict
17
17
  //= require spree/frontend/cart
18
+ //= require spree/frontend/locale
19
+ //= require spree/frontend/currency
18
20
  //= require spree/frontend/checkout
19
21
  //= require spree/frontend/checkout/address
20
22
  //= require spree/frontend/checkout/address_book
@@ -47,3 +49,11 @@ Spree.routes.api_v2_storefront_cart_remove_coupon_code = Spree.pathFor('api/v2/s
47
49
  Spree.routes.product = function(id) { return Spree.pathFor('products/' + id) }
48
50
  Spree.routes.product_related = function(id) { return Spree.pathFor('products/' + id + '/related') }
49
51
  Spree.routes.product_carousel = function (taxonId) { return Spree.pathFor('product_carousel/' + taxonId) }
52
+ Spree.routes.set_locale = function(locale) { return Spree.pathFor('locale/set?switch_to_locale=' + locale) }
53
+ Spree.routes.set_currency = function(currency) { return Spree.pathFor('currency/set?switch_to_currency=' + currency) }
54
+
55
+ Spree.showProgressBar = function () {
56
+ if (!Turbolinks.supported) { return }
57
+ Turbolinks.controller.adapter.progressBar.setValue(0)
58
+ Turbolinks.controller.adapter.progressBar.show()
59
+ }
@@ -1,6 +1,6 @@
1
1
  Spree.fetchAccount = function () {
2
2
  return $.ajax({
3
- url: Spree.pathFor('account_link')
3
+ url: Spree.localizedPathFor('account_link')
4
4
  }).done(function (data) {
5
5
  Spree.accountFetched = true
6
6
  return $('#link-to-account').html(data)
@@ -123,7 +123,7 @@ Spree.ready(function ($) {
123
123
 
124
124
  Spree.fetchCart = function () {
125
125
  return $.ajax({
126
- url: Spree.pathFor('cart_link')
126
+ url: Spree.localizedPathFor('cart_link')
127
127
  }).done(function (data) {
128
128
  Spree.cartFetched = true
129
129
  return $('#link-to-cart').html(data)
@@ -8,7 +8,7 @@ Spree.ready(function($) {
8
8
  $.ajax({
9
9
  async: false,
10
10
  method: 'GET',
11
- url: Spree.pathFor('/api/v2/storefront/countries/' + countryId + '?include=checkout_zone_applicable_states'),
11
+ url: Spree.localizedPathFor('/api/v2/storefront/countries/' + countryId + '?include=checkout_zone_applicable_states'),
12
12
  dataType: 'json'
13
13
  }).done(function(data) {
14
14
  var json = data.included;
@@ -49,7 +49,7 @@ CouponManager.prototype.sendRequest = function () {
49
49
  return $.ajax({
50
50
  async: false,
51
51
  method: 'PATCH',
52
- url: Spree.routes.api_v2_storefront_cart_apply_coupon_code,
52
+ url: Spree.routes.api_v2_storefront_cart_apply_coupon_code + '?locale=' + SPREE_LOCALE,
53
53
  dataType: 'json',
54
54
  headers: {
55
55
  'X-Spree-Order-Token': SpreeAPI.orderToken
@@ -74,7 +74,7 @@ CouponManager.prototype.sendRemoveRequest = function () {
74
74
  return $.ajax({
75
75
  async: false,
76
76
  method: 'DELETE',
77
- url: Spree.routes.api_v2_storefront_cart_remove_coupon_code + '/' + this.couponCode,
77
+ url: Spree.routes.api_v2_storefront_cart_remove_coupon_code + '/' + this.couponCode + '?locale=' + SPREE_LOCALE,
78
78
  dataType: 'json',
79
79
  headers: {
80
80
  'X-Spree-Order-Token': SpreeAPI.orderToken
@@ -0,0 +1,11 @@
1
+ Spree.ready(function ($) {
2
+ var currencySelect = $('#currency-select select')
3
+
4
+ if (currencySelect.length) {
5
+ currencySelect.on('change', function () {
6
+ currencySelect.attr('disabled')
7
+ Spree.showProgressBar()
8
+ window.location = Spree.routes.set_currency(this.value)
9
+ })
10
+ }
11
+ })
@@ -0,0 +1,11 @@
1
+ Spree.ready(function ($) {
2
+ var localeSelect = $('#locale-select select')
3
+
4
+ if (localeSelect.length) {
5
+ localeSelect.on('change', function () {
6
+ localeSelect.attr('disabled')
7
+ Spree.showProgressBar()
8
+ window.location = Spree.routes.set_locale(this.value)
9
+ })
10
+ }
11
+ })
@@ -1,6 +1,4 @@
1
1
  @import "spree/frontend/variables/variables";
2
- @import "spree/frontend/variables/bootstrap-overrides";
3
- @import "spree/frontend/variables/helper-variables";
4
2
  @import "bootstrap";
5
3
  @import "spree/frontend/bootstrap-patches";
6
4
 
@@ -32,7 +30,6 @@
32
30
  @import "spree/frontend/views/spree/errors/not_found";
33
31
  @import "spree/frontend/views/spree/shared/carousel/thumbnails";
34
32
  @import "spree/frontend/views/spree/shared/carousel/single";
35
- @import "spree/frontend/views/spree/shared/change_store";
36
33
  @import "spree/frontend/views/spree/home/index";
37
34
  @import "spree/frontend/views/spree/user_passwords/user_passwords";
38
35
  @import "spree/frontend/views/spree/user_sessions/new";
@@ -1,3 +1,4 @@
1
+ // we're keeping this file for legacy installations relying on it
1
2
  $grid-gutter-width: 19px;
2
3
  $body-color: $font-color;
3
4
  $theme-colors: (
@@ -1,3 +1,4 @@
1
+ // we're keeping this file for legacy installations relying on it
1
2
  $container-padding: 17px;
2
3
  $photo-width-to-height-ratio: 30001/ 37500;
3
4
  $photo-width-to-height-ratio-zoom: 28015 / 37500;
@@ -1,3 +1,4 @@
1
+ // main spree variables
1
2
  $primary-color: #0074c2;
2
3
  $secondary-color: #4c4c4c;
3
4
  $primary-background: #ffffff;
@@ -18,3 +19,56 @@ $spree-header-max-width: 1440px;
18
19
  $spree-header-mobile-height: 50px;
19
20
  $spree-header-tablet-height: 75px;
20
21
  $spree-header-desktop-height: 75px;
22
+
23
+ // bootstrap overrides
24
+ $grid-gutter-width: 19px;
25
+ $body-color: $font-color;
26
+ $theme-colors: (
27
+ // standard bootstrap colors
28
+ "primary": $primary-color,
29
+ "secondary": $secondary-color,
30
+ "danger": #f53737,
31
+ "info": #999999,
32
+ "warning": #ffc107,
33
+ "light-secondary": #999999,
34
+ "borders": $second-global-border,
35
+ "dark-borders": $global-border-style,
36
+ "light-background": $primary-background,
37
+ "dark-text": $font-color,
38
+ "overlay": rgba(76, 76, 76, 0.5),
39
+ "shadow": rgba(0, 0, 0, 0.16)
40
+ );
41
+ $enable-rounded: false;
42
+ $enable-shadows: false;
43
+ $enable-gradients: false;
44
+ $font-family-sans-serif: $font-family;
45
+ $font-weight-medium: 500;
46
+ .font-weight-medium {
47
+ font-weight: $font-weight-medium;
48
+ }
49
+ $btn-border-width: 2px;
50
+ $modal-dialog-margin: 0;
51
+ $grid-breakpoints: (
52
+ xs: 0,
53
+ sm: 576px,
54
+ md: 768px,
55
+ lg: 992px,
56
+ xl: 1200px
57
+ );
58
+ $container-max-widths: (
59
+ sm: 768px,
60
+ md: 992px,
61
+ lg: 1200px
62
+ );
63
+
64
+ // helper variables
65
+ $container-padding: 17px;
66
+ $photo-width-to-height-ratio: 30001/ 37500;
67
+ $photo-width-to-height-ratio-zoom: 28015 / 37500;
68
+ $thumbnails-carousel-single-height: 100% / $photo-width-to-height-ratio;
69
+ $thumbnails-carousel-single-height-zoom: 100% /
70
+ $photo-width-to-height-ratio-zoom;
71
+ $zoom-height-breakpoint: calc(
72
+ 650px / #{$photo-width-to-height-ratio-zoom} + 102px * 2
73
+ );
74
+ $spree-plp-filter-desktop-position: $spree-header-desktop-height + 77px;
@@ -0,0 +1,23 @@
1
+ module Spree
2
+ module LocaleUrls
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_action :redirect_to_default_locale
7
+ end
8
+
9
+ private
10
+
11
+ def default_url_options
12
+ return super if locale_param.nil?
13
+
14
+ super.merge(locale: locale_param)
15
+ end
16
+
17
+ def redirect_to_default_locale
18
+ return if params[:locale].blank? || supported_locale?(params[:locale])
19
+
20
+ redirect_to url_for(request.parameters.merge(locale: nil))
21
+ end
22
+ end
23
+ end
@@ -35,7 +35,7 @@ module Spree
35
35
  @order.temporary_address = !params[:save_user_address]
36
36
  unless @order.next
37
37
  flash[:error] = @order.errors.full_messages.join("\n")
38
- redirect_to(checkout_state_path(@order.state)) && return
38
+ redirect_to(spree.checkout_state_path(@order.state)) && return
39
39
  end
40
40
 
41
41
  if @order.completed?
@@ -43,7 +43,7 @@ module Spree
43
43
  flash['order_completed'] = true
44
44
  redirect_to completion_route
45
45
  else
46
- redirect_to checkout_state_path(@order.state)
46
+ redirect_to spree.checkout_state_path(@order.state)
47
47
  end
48
48
  else
49
49
  render :edit
@@ -77,7 +77,7 @@ module Spree
77
77
  if @order.state != correct_state && !skip_state_validation?
78
78
  flash.keep
79
79
  @order.update_column(:state, correct_state)
80
- redirect_to checkout_state_path(@order.state)
80
+ redirect_to spree.checkout_state_path(@order.state)
81
81
  end
82
82
  end
83
83
 
@@ -108,7 +108,7 @@ module Spree
108
108
 
109
109
  def set_state_if_present
110
110
  if params[:state]
111
- redirect_to checkout_state_path(@order.state) if @order.can_go_to_state?(params[:state]) && !skip_state_validation?
111
+ redirect_to spree.checkout_state_path(@order.state) if @order.can_go_to_state?(params[:state]) && !skip_state_validation?
112
112
  @order.state = params[:state]
113
113
  end
114
114
  end
@@ -129,8 +129,8 @@ module Spree
129
129
  end
130
130
 
131
131
  # Provides a route to redirect after order completion
132
- def completion_route(custom_params = nil)
133
- spree.order_path(@order, custom_params)
132
+ def completion_route(custom_params = {})
133
+ spree.order_path(@order, custom_params.merge(locale: locale_param))
134
134
  end
135
135
 
136
136
  def setup_for_current_state
@@ -174,14 +174,14 @@ module Spree
174
174
  params.delete(:payment_source)
175
175
 
176
176
  # Return to the Payments page if additional payment is needed.
177
- redirect_to checkout_state_path(@order.state) and return if @order.payments.valid.sum(:amount) < @order.total
177
+ redirect_to spree.checkout_state_path(@order.state) and return if @order.payments.valid.sum(:amount) < @order.total
178
178
  end
179
179
  end
180
180
 
181
181
  def remove_store_credit_payments
182
182
  if params.key?(:remove_store_credit)
183
183
  remove_store_credit_service.call(order: @order)
184
- redirect_to checkout_state_path(@order.state) and return
184
+ redirect_to spree.checkout_state_path(@order.state) and return
185
185
  end
186
186
  end
187
187
 
@@ -1,17 +1,13 @@
1
1
  module Spree
2
2
  class CurrencyController < StoreController
3
3
  def set
4
- @currency = supported_currencies.find { |currency| currency.iso_code == params[:currency] }
5
- # Make sure that we update the current order, so the currency change is reflected.
6
- current_order&.update(currency: @currency.iso_code)
7
- session[:currency] = params[:currency] if Spree::Config[:show_store_selector]
8
- respond_to do |format|
9
- format.json { render json: !@currency.nil? }
10
- format.html do
11
- # We want to go back to where we came from!
12
- redirect_back_or_default(root_path)
13
- end
4
+ new_currency = params[:switch_to_currency]&.upcase
5
+
6
+ if new_currency.present? && supported_currency?(new_currency)
7
+ current_order&.update(currency: new_currency)
8
+ session[:currency] = new_currency
14
9
  end
10
+ redirect_back_or_default(root_path(currency: new_currency))
15
11
  end
16
12
  end
17
13
  end
@@ -1,14 +1,31 @@
1
1
  module Spree
2
2
  class LocaleController < Spree::StoreController
3
+ def index
4
+ render :index, layout: false
5
+ end
6
+
3
7
  def set
4
- session['user_return_to'] = request.referer if request.referer&.starts_with?('http://' + request.host)
5
- if params[:locale] && I18n.available_locales.map(&:to_s).include?(params[:locale])
6
- session[:locale] = I18n.locale = params[:locale]
7
- flash.notice = Spree.t(:locale_changed)
8
+ new_locale = (params[:switch_to_locale] || params[:locale]).to_s
9
+
10
+ if new_locale.present? && supported_locale?(new_locale)
11
+ if should_build_new_url?
12
+ redirect_to BuildLocalizedRedirectUrl.call(
13
+ url: request.env['HTTP_REFERER'],
14
+ locale: new_locale,
15
+ default_locale: current_store.default_locale
16
+ ).value
17
+ else
18
+ redirect_to root_path(locale: new_locale)
19
+ end
8
20
  else
9
- flash[:error] = Spree.t(:locale_not_changed)
21
+ redirect_to root_path
10
22
  end
11
- redirect_back_or_default(spree.root_path)
23
+ end
24
+
25
+ private
26
+
27
+ def should_build_new_url?
28
+ request.env['HTTP_REFERER'].present? && request.env['HTTP_REFERER'] != request.env['REQUEST_URI']
12
29
  end
13
30
  end
14
31
  end
@@ -20,9 +20,9 @@ module Spree
20
20
  format.html do
21
21
  if params.key?(:checkout)
22
22
  @order.next if @order.cart?
23
- redirect_to checkout_state_path(@order.checkout_steps.first)
23
+ redirect_to spree.checkout_state_path(@order.checkout_steps.first)
24
24
  else
25
- redirect_to cart_path
25
+ redirect_to spree.cart_path
26
26
  end
27
27
  end
28
28
  end
@@ -1,17 +1,23 @@
1
1
  module Spree
2
2
  class StoreController < Spree::BaseController
3
3
  include Spree::Core::ControllerHelpers::Order
4
+ include Spree::LocaleUrls
5
+
6
+ helper 'spree/locale'
7
+ helper 'spree/currency'
4
8
 
5
9
  skip_before_action :verify_authenticity_token, only: :ensure_cart, raise: false
6
10
 
11
+ before_action :redirect_to_default_locale
12
+
7
13
  def account_link
8
14
  render partial: 'spree/shared/link_to_account'
9
- fresh_when(try_spree_current_user)
15
+ fresh_when(etag: [try_spree_current_user, I18n.locale])
10
16
  end
11
17
 
12
18
  def cart_link
13
19
  render partial: 'spree/shared/link_to_cart'
14
- fresh_when(simple_current_order)
20
+ fresh_when(etag: [simple_current_order, I18n.locale])
15
21
  end
16
22
 
17
23
  def api_tokens
@@ -65,9 +65,16 @@ module Spree
65
65
  end
66
66
 
67
67
  def user_available_addresses
68
- return unless try_spree_current_user
68
+ @user_available_addresses ||= begin
69
+ return [] unless try_spree_current_user
69
70
 
70
- try_spree_current_user.addresses.where(country: available_countries)
71
+ states = current_store.countries_available_for_checkout.each_with_object([]) do |country, memo|
72
+ memo << current_store.states_available_for_checkout(country)
73
+ end.flatten
74
+
75
+ try_spree_current_user.addresses.
76
+ where(country_id: states.pluck(:country_id).uniq)
77
+ end
71
78
  end
72
79
 
73
80
  def checkout_zone_applicable_states_for(country)
@@ -7,26 +7,6 @@ module Spree
7
7
  @body_class
8
8
  end
9
9
 
10
- def store_country_iso(store)
11
- store ||= current_store
12
- return unless store
13
- return unless store.default_country
14
-
15
- store.default_country.iso.downcase
16
- end
17
-
18
- def stores
19
- @stores ||= Spree::Store.includes(:default_country).order(:id)
20
- end
21
-
22
- def store_currency_symbol(store)
23
- store ||= current_store
24
- return unless store
25
- return unless store.default_currency
26
-
27
- ::Money::Currency.find(store.default_currency).symbol
28
- end
29
-
30
10
  def spree_breadcrumbs(taxon, _separator = '', product = nil)
31
11
  return '' if current_page?('/') || taxon.nil?
32
12
 
@@ -302,6 +282,12 @@ module Spree
302
282
  @color_option_type_name ||= Spree::OptionType.color&.name
303
283
  end
304
284
 
285
+ def country_flag_icon(country_iso_code = nil)
286
+ return if country_iso_code.blank?
287
+
288
+ content_tag :span, nil, class: "flag-icon flag-icon-#{country_iso_code.downcase}"
289
+ end
290
+
305
291
  private
306
292
 
307
293
  def formatted_price(value)