spree_frontend 4.2.0.rc5 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)