spree_storefront 5.1.8 → 5.2.0.rc1

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/account/newsletter_controller.rb +2 -0
  3. data/app/controllers/spree/errors_controller.rb +21 -0
  4. data/app/controllers/spree/newsletter_subscribers_controller.rb +27 -13
  5. data/app/controllers/spree/policies_controller.rb +2 -20
  6. data/app/controllers/spree/store_controller.rb +2 -2
  7. data/app/helpers/spree/page_helper.rb +38 -2
  8. data/app/helpers/spree/payment_methods_helper.rb +7 -0
  9. data/app/helpers/spree/storefront_helper.rb +18 -0
  10. data/app/helpers/spree/theme_helper.rb +10 -2
  11. data/app/helpers/spree/turbo_helper.rb +2 -1
  12. data/app/javascript/spree/storefront/application.js +1 -0
  13. data/app/javascript/spree/storefront/controllers/prefetch_lazy_controller.js +26 -0
  14. data/app/javascript/spree/storefront/controllers/toggle_menu_controller.js +0 -1
  15. data/app/views/layouts/spree/storefront.html.erb +5 -14
  16. data/app/views/spree/checkout/_footer.html.erb +14 -9
  17. data/app/views/spree/checkout/_line_items.html.erb +2 -2
  18. data/app/views/spree/checkout/_missing_line_items.html.erb +1 -1
  19. data/app/views/spree/checkout/_payment_method.html.erb +15 -0
  20. data/app/views/spree/checkout/_payment_methods.html.erb +1 -18
  21. data/app/views/spree/checkout/_summary.html.erb +3 -3
  22. data/app/views/spree/checkout/payment/_gateway.html.erb +3 -3
  23. data/app/views/spree/errors/403.html.erb +7 -0
  24. data/app/views/spree/errors/403.json.erb +1 -0
  25. data/app/views/spree/errors/404.html.erb +7 -0
  26. data/app/views/spree/errors/404.json.erb +1 -0
  27. data/app/views/spree/errors/422.html.erb +7 -0
  28. data/app/views/spree/errors/422.json.erb +1 -0
  29. data/app/views/spree/errors/500.html.erb +7 -0
  30. data/app/views/spree/errors/500.json.erb +1 -0
  31. data/app/views/spree/errors/503.html.erb +7 -0
  32. data/app/views/spree/errors/503.json.erb +1 -0
  33. data/app/views/spree/home/index.html.erb +3 -1
  34. data/app/views/spree/newsletter_subscribers/create.turbo_stream.erb +1 -1
  35. data/app/views/themes/default/spree/account/_orders.html.erb +1 -1
  36. data/app/views/themes/default/spree/account/addresses/index.html.erb +1 -1
  37. data/app/views/themes/default/spree/account/gift_cards/index.html.erb +1 -1
  38. data/app/views/themes/default/spree/account/store_credits/index.html.erb +1 -1
  39. data/app/views/themes/default/spree/metafields/_boolean.html.erb +5 -0
  40. data/app/views/themes/default/spree/metafields/_json.html.erb +3 -0
  41. data/app/views/themes/default/spree/metafields/_long_text.html.erb +1 -0
  42. data/app/views/themes/default/spree/metafields/_number.html.erb +1 -0
  43. data/app/views/themes/default/spree/metafields/_rich_text.html.erb +1 -0
  44. data/app/views/themes/default/spree/metafields/_short_text.html.erb +1 -0
  45. data/app/views/themes/default/spree/orders/_cart.html.erb +1 -1
  46. data/app/views/themes/default/spree/orders/_line_item.html.erb +1 -1
  47. data/app/views/themes/default/spree/page_sections/_announcement_bar.html.erb +1 -1
  48. data/app/views/themes/default/spree/page_sections/_breadcrumbs.html.erb +18 -0
  49. data/app/views/themes/default/spree/page_sections/_custom_code.html.erb +1 -1
  50. data/app/views/themes/default/spree/page_sections/_featured_posts.html.erb +1 -1
  51. data/app/views/themes/default/spree/page_sections/_featured_taxon.html.erb +1 -1
  52. data/app/views/themes/default/spree/page_sections/_featured_taxons.html.erb +1 -1
  53. data/app/views/themes/default/spree/page_sections/_footer.html.erb +2 -2
  54. data/app/views/themes/default/spree/page_sections/_header.html.erb +140 -139
  55. data/app/views/themes/default/spree/page_sections/_image_banner.html.erb +5 -4
  56. data/app/views/themes/default/spree/page_sections/_image_with_text.html.erb +3 -2
  57. data/app/views/themes/default/spree/page_sections/_newsletter.html.erb +43 -39
  58. data/app/views/themes/default/spree/page_sections/_page_title.html.erb +1 -1
  59. data/app/views/themes/default/spree/page_sections/_product_details.html.erb +47 -66
  60. data/app/views/themes/default/spree/page_sections/_rich_text.html.erb +1 -1
  61. data/app/views/themes/default/spree/page_sections/_taxon_banner.html.erb +1 -1
  62. data/app/views/themes/default/spree/page_sections/_taxon_grid.html.erb +1 -1
  63. data/app/views/themes/default/spree/page_sections/_video.html.erb +1 -1
  64. data/app/views/themes/default/spree/page_sections/nav/_desktop.html.erb +1 -1
  65. data/app/views/themes/default/spree/page_sections/nav/_mobile.html.erb +4 -9
  66. data/app/views/themes/default/spree/policies/show.html.erb +8 -9
  67. data/app/views/themes/default/spree/products/_add_to_waitlist.html.erb +3 -3
  68. data/app/views/themes/default/spree/products/_breadcrumbs.html.erb +1 -1
  69. data/app/views/themes/default/spree/products/_color_swatches.html.erb +2 -2
  70. data/app/views/themes/default/spree/products/_description.html.erb +11 -0
  71. data/app/views/themes/default/spree/products/_details.html.erb +2 -2
  72. data/app/views/themes/default/spree/products/_featured_image.html.erb +2 -8
  73. data/app/views/themes/default/spree/products/_media_gallery.html.erb +1 -1
  74. data/app/views/themes/default/spree/products/_metafields.html.erb +18 -0
  75. data/app/views/themes/default/spree/products/_quantity_selector.html.erb +1 -2
  76. data/app/views/themes/default/spree/settings/show.html.erb +2 -2
  77. data/app/views/themes/default/spree/shared/_address.html.erb +1 -1
  78. data/app/views/themes/default/spree/shared/_css_variables.html.erb +1 -1
  79. data/app/views/themes/default/spree/shared/_json_ld.html.erb +1 -1
  80. data/app/views/themes/default/spree/shared/_logo.html.erb +2 -9
  81. data/app/views/themes/default/spree/shared/_meta_tags.html.erb +6 -2
  82. data/app/views/themes/default/spree/shared/_order_details.html.erb +2 -2
  83. data/app/views/themes/default/spree/shared/_order_shipment.html.erb +1 -1
  84. data/app/views/themes/default/spree/wishlists/show.html.erb +1 -1
  85. data/config/initializers/assets.rb +3 -1
  86. data/config/locales/en.yml +5 -2
  87. data/config/routes.rb +9 -1
  88. data/lib/generators/spree/storefront/install/install_generator.rb +2 -1
  89. data/lib/generators/spree/storefront/install/templates/{application.tailwind.css → application.css} +105 -14
  90. data/lib/generators/spree/storefront/install/templates/tailwind.config.js +3 -114
  91. data/lib/spree/storefront/configuration.rb +3 -0
  92. data/lib/spree/storefront/engine.rb +5 -3
  93. data/lib/spree/storefront.rb +1 -3
  94. metadata +43 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 337793895fe097335658b9ae76e98990502e1855d07dbda8d61d606b2f1e4a46
4
- data.tar.gz: 6667eed5b01c42ae7e282379565bcf58ddccc19695d6ba1701f7a6a6bdc983aa
3
+ metadata.gz: 71287481dfb84dcfac62b0ea895963b668c6c83d01fbc885ee60bb5eb45fb246
4
+ data.tar.gz: 477e4b5aeacaaed2c4d2005530b5497544130d38da3e5e7f051115dc81a5bd65
5
5
  SHA512:
6
- metadata.gz: a833b9d290ab4f7041f72b3d556886475f58f32a218d852e27e77e0b356629b7f61d2392168f0f346ba863a588d25657ba3adc93274c8d44ed12774341286dde
7
- data.tar.gz: 32cbd6c6a59e411a5bc8e1a06e7f09c1808a8432459415d09e2f17350047887070491b87319d5c3a039897211c882f9b611925ff74c3edb94a36bef6465f2385
6
+ metadata.gz: 37a4b4d6a5e37ea78850ebcf07e2d7f37b1a6637b6f87c5d7759d9104d5ae9ce6476acdd1052009d5670255134baf7d3ed7b427edd084b25f07ab7faba9375ec
7
+ data.tar.gz: aa5c9fd3881d86d4acfeaa1c0c09a6184c6c11e3d2fcda18cc73f5738d036a077d4c915f23a264ab27950e7b71973a41bd684cc3babba930170abb35d7837906
@@ -14,8 +14,10 @@ module Spree
14
14
  }
15
15
 
16
16
  if try_spree_current_user.accepts_email_marketing?
17
+ Spree::NewsletterSubscriber.subscribe(email: try_spree_current_user.email, user: try_spree_current_user)
17
18
  track_event('subscribed_to_newsletter', event_properties)
18
19
  else
20
+ Spree::NewsletterSubscriber.find_by(email: try_spree_current_user.email)&.destroy
19
21
  track_event('unsubscribed_from_newsletter', event_properties)
20
22
  end
21
23
  end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ class ErrorsController < StoreController
3
+ def show
4
+ render "spree/errors/#{status_code}", status: status_code
5
+ end
6
+
7
+ private
8
+
9
+ def status_code
10
+ # Extract a 3‑digit code from params or path, default to “500”
11
+ code_str = params[:code].presence ||
12
+ request.path.match(%r{/(\d{3})$})&.[](1) ||
13
+ '500'
14
+ code = code_str.to_i
15
+
16
+ # Only allow valid 4xx/5xx error codes, fallback to 500
17
+ valid_errors = Rack::Utils::HTTP_STATUS_CODES.keys.select { |c| c >= 400 }
18
+ valid_errors.include?(code) ? code : 500
19
+ end
20
+ end
21
+ end
@@ -2,24 +2,19 @@ module Spree
2
2
  class NewsletterSubscribersController < StoreController
3
3
  skip_before_action :redirect_to_password
4
4
  before_action :load_newsletter_section, only: :create
5
+ rescue_from ActiveRecord::RecordNotFound, with: :subscriber_not_found
5
6
 
6
7
  # POST /newsletter_subscribers
7
8
  def create
8
- user = Spree.user_class.find_or_initialize_by(email: newsletter_params[:email])
9
+ subscriber = Spree::NewsletterSubscriber.subscribe(email: newsletter_params[:email], user: try_spree_current_user)
9
10
 
10
- if user.new_record? && user.respond_to?(:password) && user.respond_to?(:password_confirmation)
11
- user.password ||= SecureRandom.hex(16) # we need to set a password to pass validation
12
- user.password_confirmation ||= user.password
13
- end
14
-
15
- user.accepts_email_marketing = true if user.new_record? || try_spree_current_user == user
16
-
17
- if user.save
18
- track_event('subscribed_to_newsletter', { email: user.email, user: user })
19
-
20
- flash[:success] = Spree.t('storefront.newsletter_subscribers.success')
11
+ if subscriber.errors.any?
12
+ flash[:error] = subscriber.errors.full_messages.to_sentence.presence || Spree.t('something_went_wrong')
13
+ elsif subscriber.verified? && subscriber.previous_changes.blank?
14
+ flash[:notice] = Spree.t('storefront.newsletter_subscribers.already_subscribed')
21
15
  else
22
- flash[:error] = user.errors.full_messages.to_sentence.presence || Spree.t('something_went_wrong')
16
+ track_event('subscribed_to_newsletter', { email: subscriber.email, user: try_spree_current_user })
17
+ flash[:success] = Spree.t('storefront.newsletter_subscribers.success')
23
18
  end
24
19
 
25
20
  respond_to do |format|
@@ -28,8 +23,27 @@ module Spree
28
23
  end
29
24
  end
30
25
 
26
+ # GET /newsletter_subscribers/verify?token=VERIFICATION_TOKEN
27
+ def verify
28
+ raise ActiveRecord::RecordNotFound if params[:token].blank?
29
+
30
+ subscriber = ActiveRecord::Base.connected_to(role: :writing) do
31
+ Spree::NewsletterSubscriber.verify(token: params[:token])
32
+ end
33
+
34
+ if subscriber.verified?
35
+ redirect_to spree.root_path, notice: Spree.t('storefront.newsletter_subscribers.verified')
36
+ else
37
+ redirect_to spree.root_path, alert: Spree.t('storefront.newsletter_subscribers.verification_failed')
38
+ end
39
+ end
40
+
31
41
  private
32
42
 
43
+ def subscriber_not_found
44
+ redirect_to spree.root_path, alert: Spree.t('storefront.newsletter_subscribers.verification_failed')
45
+ end
46
+
33
47
  def newsletter_params
34
48
  params.require(:newsletter).permit(:email)
35
49
  end
@@ -1,26 +1,8 @@
1
1
  module Spree
2
2
  class PoliciesController < StoreController
3
+ # GET /policies/<policy_slug>
3
4
  def show
4
- if params[:id].in?(supported_policies)
5
- @policy = case params[:id]
6
- when 'privacy_policy'
7
- current_store.customer_privacy_policy
8
- when 'terms_of_service'
9
- current_store.customer_terms_of_service
10
- when 'returns_policy'
11
- current_store.customer_returns_policy
12
- when 'shipping_policy'
13
- current_store.customer_shipping_policy
14
- end
15
- else
16
- raise ActiveRecord::RecordNotFound
17
- end
18
- end
19
-
20
- private
21
-
22
- def supported_policies
23
- %w[privacy_policy terms_of_service returns_policy shipping_policy]
5
+ @policy = current_store.policies.friendly.find(params[:id])
24
6
  end
25
7
  end
26
8
  end
@@ -40,7 +40,7 @@ module Spree
40
40
  def render_404_if_store_not_exists
41
41
  return if current_store.present?
42
42
 
43
- render 'errors/404', layout: 'application', status: :not_found
43
+ render 'spree/errors/404', layout: 'application', status: :not_found
44
44
  end
45
45
 
46
46
  def current_taxon
@@ -115,7 +115,7 @@ module Spree
115
115
  end
116
116
 
117
117
  def default_title
118
- @default_title ||= current_store.name
118
+ @default_title ||= current_store.seo_title.presence || current_store.name
119
119
  end
120
120
 
121
121
  # this is a hook for subclasses to provide title
@@ -12,7 +12,7 @@ module Spree
12
12
  page ||= current_page
13
13
 
14
14
  sections = current_page_preview.present? ? current_page_preview.sections : page.sections
15
- sections_html = sections.includes(:links, :rich_text_text, :rich_text_description, { asset_attachment: :blob }, { blocks: [:rich_text_text, :links] }).map do |section|
15
+ sections_html = sections.includes(section_includes).map do |section|
16
16
  render_section(section, variables)
17
17
  end.join.html_safe
18
18
 
@@ -52,7 +52,7 @@ module Spree
52
52
 
53
53
  path = section.lazy_path(variables)
54
54
 
55
- turbo_frame_tag(css_id, src: path, loading: 'eager', class: css_class) do
55
+ turbo_frame_tag(css_id, src: path, loading: :lazy, class: css_class, data: { controller: 'prefetch-lazy', turbo_permanent: true }) do
56
56
  render('/' + section.to_partial_path, **variables)
57
57
  end
58
58
  else
@@ -68,6 +68,42 @@ module Spree
68
68
  ''
69
69
  end
70
70
 
71
+ # Returns the layout sections of the page with current theme or theme preview.
72
+ #
73
+ # @return [Array] the layout sections of the page
74
+ def layout_sections
75
+ @layout_sections ||= current_theme_or_preview.sections
76
+ end
77
+
78
+ # Renders the header sections of the page.
79
+ #
80
+ # @return [String] the rendered header sections
81
+ def render_header_sections
82
+ @render_header_sections ||= layout_sections.find_all { |section| section.role == 'header' }.map do |section|
83
+ render_section(section)
84
+ end.join.html_safe
85
+ end
86
+
87
+ # Renders the footer sections of the page.
88
+ #
89
+ # @return [String] the rendered footer sections
90
+ def render_footer_sections
91
+ @render_footer_sections ||= layout_sections.find_all { |section| section.role == 'footer' }.map do |section|
92
+ render_section(section)
93
+ end.join.html_safe
94
+ end
95
+
96
+ # Returns the includes for the section.
97
+ #
98
+ # @return [Array] the includes for the section
99
+ def section_includes
100
+ [
101
+ :links, :rich_text_text,
102
+ :rich_text_description, { asset_attachment: :blob },
103
+ { blocks: [:rich_text_text, :links] }
104
+ ]
105
+ end
106
+
71
107
  # Renders a link to the page builder for the given link.
72
108
  def page_builder_link_to(link, options = {}, &block)
73
109
  if link.present?
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ module PaymentMethodsHelper
3
+ def credit_card_icons
4
+ %w[visa mastercard american_express discover]
5
+ end
6
+ end
7
+ end
@@ -5,6 +5,24 @@ module Spree
5
5
  include Spree::ShipmentHelper
6
6
  include Heroicon::Engine.helpers
7
7
 
8
+ # Returns the cache key for the storefront including the current wishlist and order.
9
+ #
10
+ # @return [Array] The cache key
11
+ def spree_storefront_base_cache_key
12
+ @spree_storefront_base_cache_key ||= [
13
+ spree_base_cache_key,
14
+ current_wishlist,
15
+ current_order
16
+ ].compact
17
+ end
18
+
19
+ # Returns the cache scope for the storefront including the current wishlist and order.
20
+ #
21
+ # @return [Proc] The cache scope
22
+ def spree_storefront_base_cache_scope
23
+ ->(record = nil) { [*spree_storefront_base_cache_key, record].compact_blank }
24
+ end
25
+
8
26
  # Renders the storefront partials for the given section.
9
27
  #
10
28
  # @param section [String] The section to render
@@ -68,12 +68,20 @@ module Spree
68
68
  @page_builder_enabled ||= current_theme_preview.present? || current_page_preview.present?
69
69
  end
70
70
 
71
+ # Returns whether the page cache is enabled
72
+ #
73
+ # @return [Boolean] whether the page cache is enabled
74
+ def page_cache_enabled?
75
+ @page_cache_enabled ||= Spree::Storefront::Config.page_cache_enabled
76
+ end
77
+
71
78
  # Returns the theme layout sections, eg. header, footer, etc.
72
79
  #
73
80
  # @return [Hash] the theme layout sections
74
81
  def theme_layout_sections
75
- @theme_layout_sections ||= current_theme_or_preview.sections.includes(:links, :rich_text_text, :rich_text_description, { asset_attachment: :blob },
76
- { blocks: [:rich_text_text, :links] }).all.each_with_object({}) do |section, hash|
82
+ Spree::Deprecation.warn('theme_layout_sections is deprecated and will be removed in Spree 6.0. Please use render_header_sections and render_footer_sections instead.')
83
+
84
+ @theme_layout_sections ||= current_theme_or_preview.sections.includes(section_includes).all.each_with_object({}) do |section, hash|
77
85
  hash[section.type.to_s.demodulize.underscore] = section
78
86
  end
79
87
  rescue StandardError => e
@@ -7,7 +7,8 @@ module Spree
7
7
  end
8
8
 
9
9
  def spree_turbo_update_cart(order = current_order)
10
- turbo_stream.update_all '.cart-counter', order.item_count.positive? ? order.item_count : ''
10
+ turbo_stream.update_all '.cart-counter', order&.item_count&.positive? ? order&.item_count : ''
11
+ turbo_stream.update_all '.cart-total', order&.display_item_total.to_s
11
12
  end
12
13
  end
13
14
  end
@@ -47,6 +47,7 @@ const controllers = [
47
47
  'no-ui-slider',
48
48
  'pdp-desktop-gallery',
49
49
  'plp-variant-picker',
50
+ 'prefetch-lazy',
50
51
  'product-form',
51
52
  'quantity-picker',
52
53
  'read-more',
@@ -0,0 +1,26 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ rootMargin: { type: Number, default: 200 }
6
+ }
7
+
8
+ connect() {
9
+ if (this.element.getAttribute("loading") == "lazy") {
10
+ this.observer = new IntersectionObserver(this.intersect, { rootMargin: `0px 0px ${this.rootMarginValue}px 0px` })
11
+ this.observer.observe(this.element)
12
+ }
13
+ }
14
+
15
+ disconnect() {
16
+ this.observer?.disconnect()
17
+ }
18
+
19
+ intersect = (entries) => {
20
+ const lastEntry = entries.slice(-1)[0]
21
+ if (lastEntry?.isIntersecting) {
22
+ this.observer.unobserve(this.element) // We only need to do this once
23
+ this.element.setAttribute("loading", "eager")
24
+ }
25
+ }
26
+ }
@@ -17,7 +17,6 @@ export default class ToggleMenu extends Toggle {
17
17
  }
18
18
 
19
19
  toggle(e) {
20
- this.contentTarget.style.paddingBottom = `${this.contentTarget.offsetTop}px`
21
20
  super.toggle(e)
22
21
  if (this.openValue) {
23
22
  this.buttonTarget.classList.add('menu-open')
@@ -10,21 +10,12 @@
10
10
  <%= render_storefront_partials(:body_start_partials) %>
11
11
  <%= current_store.storefront_custom_code_body_start&.html_safe %>
12
12
 
13
- <% if theme_layout_sections.empty? %>
14
- <%= render template: 'errors/500' %>
15
- <% else %>
16
- <%= render_section(theme_layout_sections['announcement_bar']) if theme_layout_sections['announcement_bar'].present? %>
17
- <%= render_section(theme_layout_sections['header']) if theme_layout_sections['header'].present? %>
18
-
19
- <%= turbo_frame_tag :flash do %>
20
- <%= render('spree/shared/flashes') %>
21
- <% end %>
22
-
23
- <%= yield %>
24
-
25
- <%= render_section(theme_layout_sections['newsletter']) if theme_layout_sections['newsletter'].present? %>
26
- <%= render_section(theme_layout_sections['footer']) if theme_layout_sections['footer'].present? %>
13
+ <%= render_header_sections %>
14
+ <%= turbo_frame_tag :flash do %>
15
+ <%= render('spree/shared/flashes') %>
27
16
  <% end %>
17
+ <%= yield %>
18
+ <%= render_footer_sections %>
28
19
 
29
20
  <%= current_store.storefront_custom_code_body_end&.html_safe %>
30
21
  <%= render_storefront_partials(:body_end_partials) %>
@@ -1,10 +1,15 @@
1
- <% cache spree_base_cache_scope.call(current_store) do %>
2
- <div class="flex flex-col gap-4 text-sm">
3
- <ul class="flex justify-center flex-wrap gap-4">
4
- <%= link_to Spree.t(:privacy_policy), "/policies/privacy_policy", target: '_blank' if legal_policy('privacy_policy').present? %>
5
- <%= link_to Spree.t(:terms_of_service), "/policies/terms_of_service", target: '_blank' if legal_policy('terms_of_service').present? %>
6
- <%= link_to Spree.t(:returns_policy), "/policies/returns_policy", target: '_blank' if legal_policy('returns_policy').present? %>
7
- <%= link_to Spree.t(:shipping_policy), "/policies/shipping_policy", target: '_blank' if legal_policy('shipping_policy').present? %>
8
- </ul>
9
- </div>
1
+ <% cache spree_storefront_base_cache_scope.call(current_store) do %>
2
+ <% if current_store.links.any? %>
3
+ <div class="flex flex-col gap-4 text-sm">
4
+ <ul class="flex justify-center flex-wrap gap-4">
5
+ <% current_store.links.each do |link| %>
6
+ <li>
7
+ <%= page_builder_link_to link, { target: ('_blank' if link.open_in_new_tab), rel: ('noopener noreferrer' if link.open_in_new_tab) } do %>
8
+ <%= link.label %>
9
+ <% end %>
10
+ </li>
11
+ <% end %>
12
+ </ul>
13
+ </div>
14
+ <% end %>
10
15
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= turbo_frame_tag :checkout_line_items, id: 'line_items', target: '_top' do %>
2
- <% cache spree_base_cache_scope.call(order.line_items.cache_key_with_version) do %>
2
+ <% cache spree_storefront_base_cache_scope.call(order.line_items.cache_key_with_version) do %>
3
3
  <div class="overflow-y-auto line-items flex flex-col gap-5 pt-5 md:pt-0" data-checkout-summary-target="line_items">
4
- <%= render collection: order.line_items, partial: 'spree/checkout/line_item', cached: spree_base_cache_scope %>
4
+ <%= render collection: order.line_items, partial: 'spree/checkout/line_item', cached: spree_storefront_base_cache_scope %>
5
5
  </div>
6
6
  <% end %>
7
7
  <% end %>
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <div class="mb-5 overflow-y-auto pt-3 mx-3 lg:mx-8 lg:mt-4 lg:pt-6 line-items" data-checkout-summary-target="line_items">
12
- <%= render collection: @order.line_items_without_shipping_rates, partial: 'spree/checkout/line_item', cached: spree_base_cache_scope %>
12
+ <%= render collection: @order.line_items_without_shipping_rates, partial: 'spree/checkout/line_item', cached: spree_storefront_base_cache_scope %>
13
13
  </div>
14
14
 
15
15
  <div class="flex justify-end items-center flex-wrap mt-6">
@@ -0,0 +1,15 @@
1
+ <li class="list-group-item p-0 m-0 border-b delivery-list-item border-default">
2
+ <%= link_to spree.checkout_state_path(token: @order.token, state: 'payment', payment_method_id: method.id), class: 'custom-control custom-radio flex items-center px-5 py-4 cursor-pointer w-full' do %>
3
+ <%= radio_button_tag "order[payments_attributes][][payment_method_id]",
4
+ method.id,
5
+ selected_method == method,
6
+ class: 'mr-3' %>
7
+ <%= Spree.t(method.name, scope: :payment_methods, default: method.name) %>
8
+ <% end %>
9
+
10
+ <% if selected_method == method %>
11
+ <div class="px-5 py-4">
12
+ <%= render partial: "spree/checkout/payment/#{method.method_type}", locals: { payment_method: method } %>
13
+ </div>
14
+ <% end %>
15
+ </li>
@@ -29,24 +29,7 @@
29
29
  <% if checkout_available_payment_methods.size > 1 %>
30
30
  <ul id="payment-method-fields" class="rounded-md list-group mb-4 border border-default border-b-0 text-sm border-default">
31
31
  <% selected_method = params[:payment_method_id].present? ? checkout_available_payment_methods.find { |method| method.id.to_s == params[:payment_method_id].to_s } : checkout_available_payment_methods.first %>
32
-
33
- <% checkout_available_payment_methods.each do |method| %>
34
- <li class="list-group-item p-0 m-0 border-b delivery-list-item border-default">
35
- <%= link_to spree.checkout_state_path(token: @order.token, state: 'payment', payment_method_id: method.id), class: 'custom-control custom-radio flex items-center px-5 py-4 cursor-pointer w-full' do %>
36
- <%= radio_button_tag "order[payments_attributes][][payment_method_id]",
37
- method.id,
38
- selected_method == method,
39
- class: 'mr-3' %>
40
- <%= Spree.t(method.name, scope: :payment_methods, default: method.name) %>
41
- <% end %>
42
-
43
- <% if selected_method == method %>
44
- <div class="px-5 py-4">
45
- <%= render partial: "spree/checkout/payment/#{method.method_type}", locals: { payment_method: method } %>
46
- </div>
47
- <% end %>
48
- </li>
49
- <% end %>
32
+ <%= render collection: checkout_available_payment_methods, partial: 'spree/checkout/payment_method', as: :method, locals: { selected_method: selected_method } %>
50
33
  </ul>
51
34
  <% elsif checkout_available_payment_methods.any? %>
52
35
  <%= hidden_field_tag "order[payments_attributes][][payment_method_id]", checkout_available_payment_methods.first&.id %>
@@ -1,6 +1,6 @@
1
1
  <%= turbo_frame_tag :checkout_summary, id: 'summary' do %>
2
2
  <div class="checkout-content-summary text-sm">
3
- <% cache [*spree_base_cache_scope.call(order.cache_key_with_version), order.state] do %>
3
+ <% cache [*spree_storefront_base_cache_scope.call(order.cache_key_with_version), order.state] do %>
4
4
  <div data-hook="order_summary">
5
5
  <div class="flex justify-between items-center mb-2">
6
6
  <span><%= Spree.t(:subtotal) %>:</span>
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
  <div class="d-table-cell text-right font-weight-bold"></div>
10
10
 
11
- <% cache spree_base_cache_scope.call(order.line_item_adjustments.nonzero.cache_key_with_version) do %>
11
+ <% cache spree_storefront_base_cache_scope.call(order.line_item_adjustments.nonzero.cache_key_with_version) do %>
12
12
  <% if order.line_item_adjustments.nonzero.exists? %>
13
13
  <% order.line_item_adjustments.nonzero.promotion.eligible.group_by(&:label).each do |label, adjustments| %>
14
14
  <div class="flex justify-between items-center mb-2">
@@ -59,7 +59,7 @@
59
59
  <% end %>
60
60
 
61
61
  <% if order.payment? || order.completed? %>
62
- <% cache spree_base_cache_scope.call(order.all_adjustments.nonzero.tax.eligible.cache_key_with_version) do %>
62
+ <% cache spree_storefront_base_cache_scope.call(order.all_adjustments.nonzero.tax.eligible.cache_key_with_version) do %>
63
63
  <% order.all_adjustments.nonzero.tax.eligible.group_by(&:label).each do |label, adjustments| %>
64
64
  <div class="flex justify-between items-center mb-2">
65
65
  <span><%= label %></span>
@@ -65,9 +65,9 @@
65
65
  data: { card_validation_target: "ccType" }
66
66
  %>
67
67
 
68
- <% PaymentIcon.credit_cards.each do |card| %>
69
- <div id="credit-card-icon-<%= card.name %>" class="hidden">
70
- <%= image_tag card.path, style: 'height: 32px;' %>
68
+ <% credit_card_icons.each do |card| %>
69
+ <div id="credit-card-icon-<%= card %>" class="hidden">
70
+ <%= payment_method_icon_tag card %>
71
71
  </div>
72
72
  <% end %>
73
73
  </div>
@@ -0,0 +1,7 @@
1
+ <div class="w-full">
2
+ <div class="flex flex-col items-center justify-center py-6 gap-4">
3
+ <h2 class="text-4xl font-bold"><%= Spree.t(:forbidden) %></h2>
4
+ <p><%= Spree.t(:forbidden_message) %></p>
5
+ <%= link_to Spree.t(:back), :back, class: "btn btn-primary" %>
6
+ </div>
7
+ </div>
@@ -0,0 +1 @@
1
+ {"status":403,"error":"<%= Spree.t(:forbidden) %>"}
@@ -0,0 +1,7 @@
1
+ <div class="w-full">
2
+ <div class="flex flex-col items-center justify-center py-6 gap-4">
3
+ <h2 class="text-4xl font-bold"><%= Spree.t(:page_not_found) %></h2>
4
+ <p><%= Spree.t(:page_not_found_message) %></p>
5
+ <%= link_to Spree.t(:back), :back, class: "btn btn-primary" %>
6
+ </div>
7
+ </div>
@@ -0,0 +1 @@
1
+ {"status":404,"error":"<%= Spree.t(:page_not_found) %>"}
@@ -0,0 +1,7 @@
1
+ <div class="w-full">
2
+ <div class="flex flex-col items-center justify-center py-6 gap-4">
3
+ <h2 class="text-4xl font-bold"><%= Spree.t(:unprocessable_entity) %></h2>
4
+ <p><%= Spree.t(:unprocessable_entity_message) %></p>
5
+ <%= link_to Spree.t(:back), :back, class: "btn btn-primary" %>
6
+ </div>
7
+ </div>
@@ -0,0 +1 @@
1
+ {"status":422,"error":"<%= Spree.t(:unprocessable_entity) %>"}
@@ -0,0 +1,7 @@
1
+ <div class="w-full">
2
+ <div class="flex flex-col items-center justify-center py-6 gap-4">
3
+ <h2 class="text-4xl font-bold"><%= Spree.t(:internal_server_error) %></h2>
4
+ <p><%= Spree.t(:internal_server_error_message) %></p>
5
+ <%= link_to Spree.t(:back), :back, class: "btn btn-primary" %>
6
+ </div>
7
+ </div>
@@ -0,0 +1 @@
1
+ {"status":500,"error":"<%= Spree.t(:internal_server_error) %>"}
@@ -0,0 +1,7 @@
1
+ <div class="w-full">
2
+ <div class="flex flex-col items-center justify-center py-6 gap-4">
3
+ <h2 class="text-4xl font-bold"><%= Spree.t(:service_unavailable) %></h2>
4
+ <p><%= Spree.t(:service_unavailable_message) %></p>
5
+ <%= link_to Spree.t(:back), :back, class: "btn btn-primary" %>
6
+ </div>
7
+ </div>
@@ -0,0 +1 @@
1
+ {"status":503,"error":"<%= Spree.t(:service_unavailable) %>"}
@@ -1 +1,3 @@
1
- <%= render_page(current_page) %>
1
+ <% cache_if page_cache_enabled? && !page_builder_enabled?, spree_storefront_base_cache_scope.call(current_page), expires_in: Spree::Storefront::Config.page_cache_ttl do %>
2
+ <%= render_page(current_page) %>
3
+ <% end %>
@@ -2,6 +2,6 @@
2
2
 
3
3
  <% if @newsletter_section.present? %>
4
4
  <%= turbo_stream.update "section-#{@newsletter_section.id}" do %>
5
- <%= render 'spree/page_sections/newsletter', section: @newsletter_section %>
5
+ <%= render 'spree/page_sections/newsletter', section: @newsletter_section, loaded: true %>
6
6
  <% end %>
7
7
  <% end %>
@@ -10,7 +10,7 @@
10
10
  </tr>
11
11
  </thead>
12
12
  <tbody class="block md:table-row-group">
13
- <%= render collection: orders, partial: 'spree/account/order', cached: spree_base_cache_scope %>
13
+ <%= render collection: orders, partial: 'spree/account/order', cached: spree_storefront_base_cache_scope %>
14
14
  </tbody>
15
15
  </table>
16
16
 
@@ -9,7 +9,7 @@
9
9
  </div>
10
10
  <% if @addresses.any? %>
11
11
  <ul>
12
- <%= render partial: 'spree/account/addresses/address', collection: @addresses, cached: ->a {[*spree_base_cache_scope.call(a), try_spree_current_user.ship_address_id, try_spree_current_user.bill_address_id]}, as: :address %>
12
+ <%= render partial: 'spree/account/addresses/address', collection: @addresses, cached: ->a {[*spree_storefront_base_cache_scope.call(a), try_spree_current_user.ship_address_id, try_spree_current_user.bill_address_id]}, as: :address %>
13
13
  </ul>
14
14
  <div class="flex">
15
15
  <div data-controller="modal" data-modal-allow-background-close="true">
@@ -18,7 +18,7 @@
18
18
  </tr>
19
19
  </thead>
20
20
  <tbody class="block md:table-row-group">
21
- <%= render collection: @gift_cards, partial: 'spree/account/gift_cards/gift_card', cached: spree_base_cache_scope %>
21
+ <%= render collection: @gift_cards, partial: 'spree/account/gift_cards/gift_card', cached: spree_storefront_base_cache_scope %>
22
22
  </tbody>
23
23
  </table>
24
24
  <% else %>
@@ -21,7 +21,7 @@
21
21
  </tr>
22
22
  </thead>
23
23
  <tbody class="block md:table-row-group">
24
- <%= render collection: @store_credit_events, partial: 'spree/account/store_credits/store_credit_event', cached: spree_base_cache_scope %>
24
+ <%= render collection: @store_credit_events, partial: 'spree/account/store_credits/store_credit_event', cached: spree_storefront_base_cache_scope %>
25
25
  </tbody>
26
26
  </table>
27
27
  <% else %>
@@ -0,0 +1,5 @@
1
+ <% if metafield.value == 'true' %>
2
+ <%= Spree.t(:say_yes) %>
3
+ <% else %>
4
+ <%= Spree.t(:say_no) %>
5
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <code>
2
+ <%= metafield.value.as_json.as_json %>
3
+ </code>
@@ -0,0 +1 @@
1
+ <%= metafield.value %>
@@ -0,0 +1 @@
1
+ <%= metafield.value %>
@@ -0,0 +1 @@
1
+ <%= metafield.value.to_s %>