spree_storefront 5.0.3 → 5.1.0.beta
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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/storefront_page_builder.css +12 -7
- data/app/controllers/concerns/spree/locale_urls.rb +13 -1
- data/app/controllers/concerns/spree/storefront/devise_concern.rb +42 -0
- data/app/controllers/spree/account/wished_items_controller.rb +0 -2
- data/app/controllers/spree/addresses_controller.rb +5 -1
- data/app/controllers/spree/checkout_controller.rb +27 -9
- data/app/controllers/spree/contacts_controller.rb +1 -1
- data/app/controllers/spree/products_controller.rb +1 -3
- data/app/controllers/spree/store_controller.rb +16 -9
- data/app/controllers/spree/taxons_controller.rb +1 -3
- data/app/helpers/spree/analytics_helper.rb +6 -2
- data/app/helpers/spree/checkout_analytics_helper.rb +1 -1
- data/app/helpers/spree/checkout_helper.rb +1 -1
- data/app/helpers/spree/filters_helper.rb +1 -1
- data/app/helpers/spree/fonts_helper.rb +3 -1
- data/app/helpers/spree/page_helper.rb +15 -0
- data/app/helpers/spree/products_helper.rb +13 -1
- data/app/helpers/spree/storefront_helper.rb +12 -0
- data/app/helpers/spree/storefront_locale_helper.rb +3 -0
- data/app/helpers/spree/theme_helper.rb +76 -0
- data/app/helpers/spree/wishlist_helper.rb +3 -0
- data/app/javascript/spree/storefront/controllers/product_form_controller.js +21 -18
- data/app/javascript/spree/storefront/controllers/quantity_picker_controller.js +16 -9
- data/app/javascript/spree/storefront/controllers/slideover_controller.js +2 -0
- data/app/javascript/spree/storefront/controllers/wished_item_controller.js +4 -2
- data/app/views/devise/registrations/_form.html.erb +2 -2
- data/app/views/devise/sessions/new.html.erb +16 -0
- data/app/views/layouts/spree/checkout.html.erb +1 -1
- data/app/views/layouts/spree/storefront.html.erb +1 -1
- data/app/views/spree/account/wished_items/create.turbo_stream.erb +1 -0
- data/app/views/spree/addresses/edit.html.erb +4 -0
- data/app/views/spree/addresses/new.html.erb +3 -0
- data/app/views/spree/checkout/edit.html.erb +5 -3
- data/app/views/spree/line_items/create.turbo_stream.erb +1 -0
- data/app/views/spree/line_items/destroy.turbo_stream.erb +2 -0
- data/app/views/spree/products/show.html.erb +2 -1
- data/app/views/themes/default/spree/account/addresses/_address.html.erb +14 -4
- data/app/views/themes/default/spree/account/addresses/_edit_address_modal.html.erb +38 -0
- data/app/views/themes/default/spree/account/addresses/_new_address_modal.html.erb +38 -0
- data/app/views/themes/default/spree/account/addresses/index.html.erb +22 -2
- data/app/views/themes/default/spree/orders/_line_item_quantity.html.erb +1 -1
- data/app/views/themes/default/spree/orders/edit.html.erb +2 -0
- data/app/views/themes/default/spree/page_sections/_newsletter.html.erb +1 -1
- data/app/views/themes/default/spree/page_sections/_product_grid.html.erb +16 -9
- data/app/views/themes/default/spree/products/_add_to_cart_button.html.erb +8 -2
- data/app/views/themes/default/spree/products/_add_to_wishlist.html.erb +2 -0
- data/app/views/themes/default/spree/products/filters/_taxons.erb +5 -5
- data/app/views/themes/default/spree/shared/_error_messages.html.erb +1 -1
- data/lib/generators/spree/storefront/devise/devise_generator.rb +47 -0
- data/lib/generators/spree/storefront/devise/templates/user_passwords_controller.rb +17 -0
- data/lib/generators/spree/storefront/devise/templates/user_registrations_controller.rb +17 -0
- data/lib/generators/spree/storefront/devise/templates/user_sessions_controller.rb +17 -0
- data/lib/spree/storefront/engine.rb +7 -1
- metadata +13 -6
@@ -1,9 +1,16 @@
|
|
1
1
|
module Spree
|
2
2
|
module ThemeHelper
|
3
|
+
# Returns the current page, if not found it will fallback to the homepage
|
4
|
+
#
|
5
|
+
# @return [Spree::Page] the current page
|
3
6
|
def current_page
|
4
7
|
@current_page ||= current_theme.pages.find_by(type: 'Spree::Pages::Homepage')
|
5
8
|
end
|
6
9
|
|
10
|
+
# Returns the current theme, if not found it will fallback to the default theme
|
11
|
+
# If `theme_id` is provided in the params, it will return the theme with the given id
|
12
|
+
#
|
13
|
+
# @return [Spree::Theme] the current theme
|
7
14
|
def current_theme
|
8
15
|
@current_theme ||= if params[:theme_id].present?
|
9
16
|
current_store.themes.find_by(id: params[:theme_id])
|
@@ -14,34 +21,56 @@ module Spree
|
|
14
21
|
@current_theme ||= current_store.themes.first
|
15
22
|
end
|
16
23
|
|
24
|
+
# Returns the current theme preview
|
25
|
+
#
|
26
|
+
# @return [Spree::ThemePreview] the current theme preview
|
17
27
|
def current_theme_preview
|
18
28
|
return if params[:theme_preview_id].blank?
|
19
29
|
|
20
30
|
@current_theme_preview ||= current_theme.previews.find_by(id: params[:theme_preview_id])
|
21
31
|
end
|
22
32
|
|
33
|
+
# Returns the current page preview
|
34
|
+
#
|
35
|
+
# @return [Spree::PagePreview] the current page preview
|
23
36
|
def current_page_preview
|
24
37
|
return if params[:page_preview_id].blank?
|
25
38
|
|
26
39
|
@current_page_preview ||= current_page.previews.find_by(id: params[:page_preview_id])
|
27
40
|
end
|
28
41
|
|
42
|
+
# Returns the current page or page preview, preview takes priority
|
43
|
+
#
|
44
|
+
# @return [Spree::Page] the current page or page preview
|
29
45
|
def current_page_or_preview
|
30
46
|
@current_page_or_preview ||= current_page_preview || current_page
|
31
47
|
end
|
32
48
|
|
49
|
+
# Returns the current theme or theme preview, preview takes priority
|
50
|
+
#
|
51
|
+
# @return [Spree::Theme] the current theme or theme preview
|
33
52
|
def current_theme_or_preview
|
34
53
|
@current_theme_or_preview ||= current_theme_preview || current_theme
|
35
54
|
end
|
36
55
|
|
56
|
+
# Returns the logo set in the `Spree::PageSections::Header` section
|
57
|
+
#
|
58
|
+
# @return [ActiveStorage::Attachment] the logo
|
37
59
|
def current_header_logo
|
38
60
|
@current_header_logo ||= current_theme_or_preview.sections.find_by(type: 'Spree::PageSections::Header')&.logo
|
39
61
|
end
|
40
62
|
|
63
|
+
# Returns whether the page builder is enabled
|
64
|
+
# It checks if there is a theme preview or page preview and if the `page_builder` param is set to `true`
|
65
|
+
#
|
66
|
+
# @return [Boolean] whether the page builder is enabled
|
41
67
|
def page_builder_enabled?
|
42
68
|
@page_builder_enabled ||= (current_theme_preview.present? || current_page_preview.present?) && params[:page_builder] == 'true'
|
43
69
|
end
|
44
70
|
|
71
|
+
# Returns the theme layout sections, eg. header, footer, etc.
|
72
|
+
#
|
73
|
+
# @return [Hash] the theme layout sections
|
45
74
|
def theme_layout_sections
|
46
75
|
@theme_layout_sections ||= current_theme_or_preview.sections.includes(:links, { asset_attachment: :blob },
|
47
76
|
{ blocks: [:rich_text_text, :links] }).all.each_with_object({}) do |section, hash|
|
@@ -55,6 +84,11 @@ module Spree
|
|
55
84
|
{}
|
56
85
|
end
|
57
86
|
|
87
|
+
# Returns the theme setting for the given name
|
88
|
+
# if preview is present, it will return the preview setting, otherwise it will return the theme setting
|
89
|
+
#
|
90
|
+
# @param name [String] the name of the theme setting
|
91
|
+
# @return [String] the theme setting
|
58
92
|
def theme_setting(name)
|
59
93
|
if current_theme_preview.present?
|
60
94
|
current_theme_preview.preferences.with_indifferent_access[name]
|
@@ -64,6 +98,9 @@ module Spree
|
|
64
98
|
end
|
65
99
|
|
66
100
|
# This helper allows us to specify opacity in Tailwind's color palette
|
101
|
+
#
|
102
|
+
# @param name [String] the name of the theme setting
|
103
|
+
# @return [String] the theme setting
|
67
104
|
def theme_setting_rgb_components(name)
|
68
105
|
hex_color = theme_setting(name)
|
69
106
|
return unless hex_color.present?
|
@@ -73,6 +110,10 @@ module Spree
|
|
73
110
|
end
|
74
111
|
|
75
112
|
# https://makandracards.com/makandra/496431-ruby-how-to-convert-hex-color-codes-to-rgb-or-rgba
|
113
|
+
# Converts a hex color to rgb
|
114
|
+
#
|
115
|
+
# @param hex [String] the hex color
|
116
|
+
# @return [String] the rgb color
|
76
117
|
def hex_color_to_rgb(hex)
|
77
118
|
return unless hex.present?
|
78
119
|
|
@@ -80,6 +121,10 @@ module Spree
|
|
80
121
|
"rgb(#{rgb.join(', ')})"
|
81
122
|
end
|
82
123
|
|
124
|
+
# Converts a hex color to rgba
|
125
|
+
#
|
126
|
+
# @param hex [String] the hex color
|
127
|
+
# @return [String] the rgba color
|
83
128
|
def hex_color_to_rgba(hex)
|
84
129
|
return unless hex.present?
|
85
130
|
|
@@ -88,6 +133,10 @@ module Spree
|
|
88
133
|
"rgba(#{rgb.join(', ')}, #{opacity.round(2)})"
|
89
134
|
end
|
90
135
|
|
136
|
+
# Returns the section inline CSS styles
|
137
|
+
#
|
138
|
+
# @param section [Spree::PageSection] the section
|
139
|
+
# @return [String] the section inline CSS styles
|
91
140
|
def section_styles(section)
|
92
141
|
styles = {}
|
93
142
|
|
@@ -116,6 +165,10 @@ module Spree
|
|
116
165
|
styles.map { |k, v| "#{k}: #{v}" }.join(';')
|
117
166
|
end
|
118
167
|
|
168
|
+
# Returns the section heading inline CSS styles
|
169
|
+
#
|
170
|
+
# @param section [Spree::PageSection] the section
|
171
|
+
# @return [String] the section heading inline CSS styles
|
119
172
|
def section_heading_styles(section)
|
120
173
|
styles = {}
|
121
174
|
|
@@ -128,6 +181,11 @@ module Spree
|
|
128
181
|
styles.compact_blank.map { |k, v| "#{k}: #{v}" }.join(';')
|
129
182
|
end
|
130
183
|
|
184
|
+
# Returns the block HTML attributes
|
185
|
+
# it automatically adds data attributes for page builder
|
186
|
+
#
|
187
|
+
# @param block [Spree::PageBlock] the block
|
188
|
+
# @return [Hash] the block attributes
|
131
189
|
def block_attributes(block, allowed_styles: :all)
|
132
190
|
has_width_desktop = block.respond_to?(:preferred_width_desktop) && block.preferred_width_desktop.present? ? "width-desktop='true'" : nil
|
133
191
|
|
@@ -147,6 +205,11 @@ module Spree
|
|
147
205
|
tag.attributes(attributes)
|
148
206
|
end
|
149
207
|
|
208
|
+
# Returns the link HTML attributes
|
209
|
+
# it automatically adds data attributes for page builder
|
210
|
+
#
|
211
|
+
# @param link [Spree::PageLink] the link
|
212
|
+
# @return [Hash] the link attributes
|
150
213
|
def link_attributes(link, as_html: true)
|
151
214
|
parent_type = case link.parent_type
|
152
215
|
when 'Spree::PageSection'
|
@@ -184,6 +247,11 @@ module Spree
|
|
184
247
|
end
|
185
248
|
end
|
186
249
|
|
250
|
+
# Returns the block inline CSS styles
|
251
|
+
#
|
252
|
+
# @param block [Spree::PageBlock] the block
|
253
|
+
# @param allowed_styles [Symbol] the allowed styles, if not provided, all styles will be returned
|
254
|
+
# @return [String] the block inline CSS styles
|
187
255
|
def block_styles(block, allowed_styles: :all)
|
188
256
|
styles = {}
|
189
257
|
|
@@ -229,12 +297,20 @@ module Spree
|
|
229
297
|
styles.map { |k, v| "#{k}: #{v}" }.join(';')
|
230
298
|
end
|
231
299
|
|
300
|
+
# Returns the block background color style
|
301
|
+
#
|
302
|
+
# @param block [Spree::PageBlock] the block
|
303
|
+
# @return [String] the block background color style
|
232
304
|
def block_background_color_style(block)
|
233
305
|
return nil unless block.respond_to?(:preferred_background_color) && block.preferred_background_color.present?
|
234
306
|
|
235
307
|
"background-color: #{block.preferred_background_color};"
|
236
308
|
end
|
237
309
|
|
310
|
+
# Returns the block CSS classes
|
311
|
+
#
|
312
|
+
# @param block [Spree::PageBlock] the block
|
313
|
+
# @return [String] the block CSS classes
|
238
314
|
def block_css_classes(block)
|
239
315
|
classes = []
|
240
316
|
classes << "justify-#{block.preferred_justify}" if block.respond_to?(:preferred_justify) && block.preferred_justify.present?
|
@@ -28,20 +28,12 @@ export default class extends Controller {
|
|
28
28
|
}
|
29
29
|
|
30
30
|
connect() {
|
31
|
-
|
32
|
-
|
33
|
-
if (option.checked) {
|
34
|
-
selectedOptions.add(option.dataset.optionId)
|
35
|
-
}
|
36
|
-
})
|
37
|
-
const requiredOptions = new Set(this.requiredOptionsValue)
|
31
|
+
if (this.hasAddToWishlistTarget && this.variantFromOptionsDisabledValue) {
|
32
|
+
const notSelectedOptions = this.getNotSelectedOptions()
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
43
|
-
if (this.hasAddToWishlistTarget && this.variantFromOptionsDisabledValue && this.notSelectedOptions.length === 0) {
|
44
|
-
this.addToWishlistTarget.disabled = true
|
34
|
+
if (notSelectedOptions.length === 0) {
|
35
|
+
this.addToWishlistTarget.disabled = true
|
36
|
+
}
|
45
37
|
}
|
46
38
|
|
47
39
|
if (this.hasDesktopMediaGalleryTarget && this.hasProductDetailsTarget) {
|
@@ -56,14 +48,14 @@ export default class extends Controller {
|
|
56
48
|
this.submitTargets.forEach((button) => button.addEventListener('turbo-stream-form:submit-end', this.enableForm))
|
57
49
|
}
|
58
50
|
|
59
|
-
disconnect() {
|
60
|
-
this.submitTargets.forEach((button) => button.removeEventListener('click', this.showNotSelectedOptions))
|
61
|
-
}
|
62
|
-
|
63
51
|
showNotSelectedOptions = (e) => {
|
52
|
+
const notSelectedOptions = this.getNotSelectedOptions()
|
53
|
+
|
54
|
+
if (!notSelectedOptions.length) return
|
55
|
+
|
64
56
|
e.preventDefault()
|
65
57
|
|
66
|
-
|
58
|
+
notSelectedOptions.forEach((option, index) => {
|
67
59
|
const fieldSetElement = this.element.querySelector(`[data-option-id="${option}"]`)
|
68
60
|
if (index === 0) {
|
69
61
|
const toggleElement = fieldSetElement.querySelector('[data-controller="dropdown"]')
|
@@ -133,4 +125,15 @@ export default class extends Controller {
|
|
133
125
|
enableForm = () => {
|
134
126
|
this.disabledValue = false
|
135
127
|
}
|
128
|
+
|
129
|
+
getNotSelectedOptions() {
|
130
|
+
const selectedOptions = new Set()
|
131
|
+
this.optionTargets.forEach((option) => {
|
132
|
+
if (option.checked) {
|
133
|
+
selectedOptions.add(option.dataset.optionId)
|
134
|
+
}
|
135
|
+
})
|
136
|
+
const requiredOptions = new Set(this.requiredOptionsValue)
|
137
|
+
return [...requiredOptions].filter((x) => !selectedOptions.has(x))
|
138
|
+
}
|
136
139
|
}
|
@@ -3,41 +3,48 @@ import { Controller } from "@hotwired/stimulus"
|
|
3
3
|
export default class extends Controller {
|
4
4
|
static targets = [ 'quantity', 'increase', 'decrease' ]
|
5
5
|
|
6
|
+
static values = {
|
7
|
+
min: { type: Number, default: 1 },
|
8
|
+
max: { type: Number, default: 9999 }
|
9
|
+
}
|
10
|
+
|
11
|
+
static classes = ['disabled']
|
12
|
+
|
6
13
|
connect() {
|
7
|
-
if (this.quantity <=
|
14
|
+
if (this.quantity <= this.minValue) this.disableButton(this.decreaseTarget)
|
8
15
|
}
|
9
16
|
|
10
17
|
get quantity() {
|
11
|
-
return parseInt(this.quantityTarget.value) ||
|
18
|
+
return parseInt(this.quantityTarget.value) || this.minValue
|
12
19
|
}
|
13
20
|
|
14
21
|
get maxQuantity() {
|
15
|
-
return parseInt(this.quantityTarget.max) ||
|
22
|
+
return parseInt(this.quantityTarget.max) || this.maxValue
|
16
23
|
}
|
17
24
|
|
18
25
|
set quantity(value) {
|
19
|
-
this.quantityTarget.value = parseInt(value) ||
|
26
|
+
this.quantityTarget.value = parseInt(value) || this.minValue
|
20
27
|
}
|
21
28
|
|
22
29
|
increase() {
|
23
30
|
if (this.quantity < this.maxQuantity) this.quantity = this.quantity + 1
|
24
|
-
if (this.quantity >
|
31
|
+
if (this.quantity > this.minValue) this.enableButton(this.decreaseTarget)
|
25
32
|
if (this.quantity == this.maxQuantity && this.increaseTarget.type != 'submit') this.disableButton(this.increaseTarget)
|
26
33
|
}
|
27
34
|
|
28
35
|
decrease() {
|
29
|
-
if (this.quantity >
|
30
|
-
if (this.quantity ==
|
36
|
+
if (this.quantity > this.minValue) this.quantity = this.quantity - 1
|
37
|
+
if (this.quantity == this.minValue && this.decreaseTarget.type != 'submit') this.disableButton(this.decreaseTarget)
|
31
38
|
if (this.quantity < this.maxQuantity) this.enableButton(this.increaseTarget)
|
32
39
|
}
|
33
40
|
|
34
41
|
disableButton(button) {
|
35
42
|
button.setAttribute('disabled', 'disabled')
|
36
|
-
button.classList.add(
|
43
|
+
button.classList.add(...this.disabledClasses)
|
37
44
|
}
|
38
45
|
|
39
46
|
enableButton(button) {
|
40
47
|
button.removeAttribute('disabled')
|
41
|
-
button.classList.remove(
|
48
|
+
button.classList.remove(...this.disabledClasses)
|
42
49
|
}
|
43
50
|
}
|
@@ -6,6 +6,8 @@ export default class extends Controller {
|
|
6
6
|
static targets = ['add', 'remove']
|
7
7
|
static values = {
|
8
8
|
variantId: String,
|
9
|
+
createWishlistPath: String,
|
10
|
+
destroyWishlistPath: String
|
9
11
|
}
|
10
12
|
|
11
13
|
connect() {
|
@@ -27,7 +29,7 @@ export default class extends Controller {
|
|
27
29
|
|
28
30
|
const headers = {}
|
29
31
|
|
30
|
-
const response = await post(
|
32
|
+
const response = await post(this.createWishlistPathValue, {
|
31
33
|
body: body,
|
32
34
|
headers: headers,
|
33
35
|
responseKind: 'turbo-stream'
|
@@ -45,7 +47,7 @@ export default class extends Controller {
|
|
45
47
|
|
46
48
|
const headers = {}
|
47
49
|
|
48
|
-
const response = await destroy(
|
50
|
+
const response = await destroy(this.destroyWishlistPathValue, {
|
49
51
|
headers: headers,
|
50
52
|
responseKind: 'turbo-stream'
|
51
53
|
})
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="card-dialog mx-auto lg:w-1/3">
|
2
2
|
<% unless params[:checkout] %>
|
3
|
-
<h3 class="mb-5 font-semibold"><%= Spree.t(:
|
3
|
+
<h3 class="mb-5 font-semibold"><%= Spree.t(:create_a_new_account) %></h3>
|
4
4
|
<% end %>
|
5
5
|
<%= render partial: 'spree/shared/error_messages', locals: { target: @user } %>
|
6
6
|
<%= form_for resource, as: :spree_user, url: spree.registration_path(checkout: params[:checkout]), data: { turbo: false } do |f| %>
|
@@ -16,6 +16,6 @@
|
|
16
16
|
</div>
|
17
17
|
</div>
|
18
18
|
</div>
|
19
|
-
<%= f.submit Spree.t(:
|
19
|
+
<%= f.submit Spree.t(:create_a_new_account), class: 'btn-primary block w-full lg:w-48 text-center mx-auto' %>
|
20
20
|
<% end %>
|
21
21
|
</div>
|
@@ -21,5 +21,21 @@
|
|
21
21
|
</div>
|
22
22
|
<% end %>
|
23
23
|
<%= render "devise/shared/links" %>
|
24
|
+
|
25
|
+
<% if current_order.present? &&
|
26
|
+
current_store&.prefers_guest_checkout? &&
|
27
|
+
stored_location&.include?(spree.checkout_path(current_order.token))
|
28
|
+
%>
|
29
|
+
<div class="relative my-5 flex items-center">
|
30
|
+
<div class="flex-grow border-t border-gray-200"></div>
|
31
|
+
<span class="mx-4 text-sm text-gray-500 uppercase"><%= Spree.t(:or) %></span>
|
32
|
+
<div class="flex-grow border-t border-gray-200"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="flex flex-col items-center gap-4">
|
36
|
+
<p class="text-sm text-gray-600"><%= Spree.t(:continue_without_logging_in) %></p>
|
37
|
+
<%= link_to Spree.t(:continue_as_guest), spree.checkout_path(current_order.token, guest: true), class: 'btn btn-secondary w-full max-w-sm', data: { turbo: false } %>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
24
40
|
</div>
|
25
41
|
<% end %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<%= render 'spree/shared/head' %>
|
9
9
|
<%= render 'spree/shared/custom_head' %>
|
10
10
|
</head>
|
11
|
-
<body id="checkout-page" class="w-full bg-background text-text">
|
11
|
+
<body id="checkout-page" class="theme-<%= current_theme.class.name.demodulize.underscore %> w-full bg-background text-text">
|
12
12
|
<%= render_storefront_partials(:body_start_partials) %>
|
13
13
|
<%= current_store.storefront_custom_code_body_start&.html_safe %>
|
14
14
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<%= render 'spree/shared/json_ld' %>
|
7
7
|
<%= current_store.storefront_custom_code_head&.html_safe %>
|
8
8
|
</head>
|
9
|
-
<body class="bg-background w-full text-text <%= current_page&.slug %>-page <% if current_theme_preview.present? %>inside-page-builder<% end %>">
|
9
|
+
<body class="theme-<%= current_theme.class.name.demodulize.underscore %> bg-background w-full text-text <%= current_page&.slug %>-page <% if current_theme_preview.present? %>inside-page-builder<% end %>">
|
10
10
|
<%= render_storefront_partials(:body_start_partials) %>
|
11
11
|
<%= current_store.storefront_custom_code_body_start&.html_safe %>
|
12
12
|
|
@@ -15,6 +15,10 @@
|
|
15
15
|
</div>
|
16
16
|
<% end %>
|
17
17
|
<% end %>
|
18
|
+
<% elsif turbo_frame_request? %>
|
19
|
+
<%= turbo_frame_tag "edit_address_modal_#{@address.id}" do %>
|
20
|
+
<%= render partial: 'spree/account/addresses/edit_address_modal', locals: { address: @address } %>
|
21
|
+
<% end %>
|
18
22
|
<% else %>
|
19
23
|
<div class="page-container grid grid-cols-1 lg:grid-cols-12 lg:gap-6 lg:mt-6">
|
20
24
|
<div class="lg:col-span-2">
|
@@ -15,6 +15,9 @@
|
|
15
15
|
<% end %>
|
16
16
|
</div>
|
17
17
|
<% end %>
|
18
|
+
<%= turbo_frame_tag :new_address_modal do %>
|
19
|
+
<%= render partial: 'spree/account/addresses/new_address_modal', locals: { address: @address } %>
|
20
|
+
<% end %>
|
18
21
|
<% else %>
|
19
22
|
<% if params[:checkout].present? %>
|
20
23
|
<div class="card-dialog mx-auto lg:w-1/3">
|
@@ -39,7 +39,7 @@
|
|
39
39
|
<%= Spree.t(:ship_address) %>
|
40
40
|
</div>
|
41
41
|
<div class="px-5 word-break">
|
42
|
-
<%= @order.ship_address.to_s.gsub('<br/>', ', ')
|
42
|
+
<%= sanitize(@order.ship_address.to_s.gsub('<br/>', ', ')) %>
|
43
43
|
</div>
|
44
44
|
</div>
|
45
45
|
<div class="text-xs">
|
@@ -82,11 +82,13 @@
|
|
82
82
|
<%= render partial: 'spree/checkout/payment', locals: { order: @order } %>
|
83
83
|
<% elsif @order.delivery? %>
|
84
84
|
<%= render partial: 'spree/checkout/delivery', locals: { order: @order } %>
|
85
|
-
<%
|
85
|
+
<% elsif step = @order.checkout_steps.find { |s| s == @order.state } %>
|
86
86
|
<%= form_for @order, url: spree.update_checkout_path(@order.token, @order.state), html: { id: "checkout_form_#{@order.state}" } do |form| %>
|
87
87
|
<div>
|
88
88
|
<%= form.hidden_field :state_lock_version unless @order.errors.any? %>
|
89
|
-
|
89
|
+
<% if step.in?(%w[address delivery payment confirm]) %>
|
90
|
+
<%= render partial: "spree/checkout/#{step}", locals: { form: form } %>
|
91
|
+
<% end %>
|
90
92
|
</div>
|
91
93
|
<div>
|
92
94
|
<%= button_tag Spree.t(:save_and_continue),
|
@@ -1 +1,2 @@
|
|
1
|
-
<%= render_page(current_page_or_preview, product: @product) %>
|
1
|
+
<%= render_page(current_page_or_preview, product: @product) %>
|
2
|
+
<%= render_storefront_partials(:product_partials) %>
|
@@ -1,10 +1,20 @@
|
|
1
1
|
<li class="p-4 my-4 border border-accent lg:flex justify-between relative" id="<%= dom_id(address) %>">
|
2
2
|
<%= render 'spree/shared/address', address: address %>
|
3
3
|
<div class="flex gap-6 h-6 lg:h-10 mt-6 lg:mt-0">
|
4
|
-
|
5
|
-
<%=
|
6
|
-
|
7
|
-
|
4
|
+
<div data-controller="modal" data-modal-allow-background-close="true">
|
5
|
+
<%= button_tag type: "button", class: 'flex gap-2 lg:p-2', data: { action: "click->modal#open" } do %>
|
6
|
+
<%= render 'spree/shared/icons/edit' %>
|
7
|
+
<span class="uppercase text-sm font-semibold tracking-widest"><%= Spree.t(:edit) %></span>
|
8
|
+
<% end %>
|
9
|
+
<%= turbo_frame_tag "edit_address_modal_#{address.id}",
|
10
|
+
src: spree.edit_address_path(address),
|
11
|
+
loading: :lazy,
|
12
|
+
data: {
|
13
|
+
modal_target: "container",
|
14
|
+
action: "click->modal#closeBackground keyup@window->modal#closeWithKeyboard"
|
15
|
+
},
|
16
|
+
class: "hidden animated fadeIn fixed inset-0 overflow-y-auto flex items-center justify-center z-[9999]" %>
|
17
|
+
</div>
|
8
18
|
<div
|
9
19
|
data-controller="modal"
|
10
20
|
data-modal-allow-background-close="true"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<div class="bg-white h-[90vh] lg:h-[70vh] w-full lg:w-1/3 flex flex-col overflow-hidden">
|
2
|
+
<%= form_for @address, method: :put, html: { class: "flex flex-col h-full", data: { turbo_frame: "_top" } } do |f| %>
|
3
|
+
<div class="px-8 py-6 border-b shrink-0">
|
4
|
+
<div class="flex justify-between items-center">
|
5
|
+
<h3 class="text-xl lg:text-2xl font-medium lg:font-semibold capitalize">
|
6
|
+
<%= Spree.t(:edit_address) %>
|
7
|
+
</h3>
|
8
|
+
<button data-action="click->modal#close" class="ml-4">
|
9
|
+
<%= render 'spree/shared/icons/close' %>
|
10
|
+
<span class="sr-only"><%= Spree.t(:close) %></span>
|
11
|
+
</button>
|
12
|
+
</div>
|
13
|
+
<%= render 'spree/shared/error_messages', target: @address, class: 'alert-error text-center mt-4 p-2' %>
|
14
|
+
</div>
|
15
|
+
<div class="overflow-y-auto px-8 py-2 grow">
|
16
|
+
<div class="py-4 text-left">
|
17
|
+
<%= render 'spree/addresses/form',
|
18
|
+
address_name: 'address',
|
19
|
+
address_form: f,
|
20
|
+
address_type: 'shipping',
|
21
|
+
address: @address %>
|
22
|
+
</div>
|
23
|
+
<%= label_tag "default_shipping", class: "flex items-center gap-2 text-sm mb-4" do %>
|
24
|
+
<%= check_box_tag "default_shipping", "true", @address.user_default_shipping?, class: 'input-checkbox input-address-default', disabled: @address.user_default_shipping? %>
|
25
|
+
<%= Spree.t('address_book.set_as_default_delivery_address') %>
|
26
|
+
<% end %>
|
27
|
+
<%= label_tag "default_billing", class: "flex items-center gap-2 text-sm mb-4" do %>
|
28
|
+
<%= check_box_tag "default_billing", "true", @address.user_default_billing?, class: 'input-checkbox input-address-default', disabled: @address.user_default_billing? %>
|
29
|
+
<%= Spree.t('address_book.set_as_default_billing_address') %>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
<div class="border-t border-default px-8 py-4 flex justify-end gap-8 shrink-0">
|
33
|
+
<%= button_tag Spree.t(:cancel), class: 'uppercase text-sm font-semibold', data: { action: 'click->modal#close' } %>
|
34
|
+
<%= hidden_field_tag :from_modal, "true" %>
|
35
|
+
<%= f.submit Spree.t(:update), class: 'btn-primary w-48' %>
|
36
|
+
</div>
|
37
|
+
<% end %>
|
38
|
+
</div>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<div class="bg-white h-[90vh] lg:h-[70vh] w-full lg:w-1/3 flex flex-col overflow-hidden">
|
2
|
+
<%= form_for @address, html: { class: "flex flex-col h-full", data: { turbo_frame: "_top" } } do |f| %>
|
3
|
+
<div class="px-8 py-6 border-b shrink-0">
|
4
|
+
<div class="flex justify-between items-center">
|
5
|
+
<h3 class="text-xl lg:text-2xl font-medium lg:font-semibold capitalize">
|
6
|
+
<%= Spree.t(:add_address) %>
|
7
|
+
</h3>
|
8
|
+
<button data-action="click->modal#close" class="ml-4">
|
9
|
+
<%= render 'spree/shared/icons/close' %>
|
10
|
+
<span class="sr-only"><%= Spree.t(:close) %></span>
|
11
|
+
</button>
|
12
|
+
</div>
|
13
|
+
<%= render 'spree/shared/error_messages', target: @address, class: 'alert-error text-center mt-4 p-2' %>
|
14
|
+
</div>
|
15
|
+
<div class="overflow-y-auto px-8 py-2 grow">
|
16
|
+
<div class="py-4 text-left">
|
17
|
+
<%= render 'spree/addresses/form',
|
18
|
+
address_name: 'address',
|
19
|
+
address_form: f,
|
20
|
+
address_type: 'shipping',
|
21
|
+
address: @address %>
|
22
|
+
</div>
|
23
|
+
<%= label_tag "default_shipping", class: "flex items-center gap-2 text-sm mb-4" do %>
|
24
|
+
<%= check_box_tag "default_shipping", "true", true, class: 'input-checkbox' %>
|
25
|
+
<%= Spree.t('address_book.set_as_default_delivery_address') %>
|
26
|
+
<% end %>
|
27
|
+
<%= label_tag "default_billing", class: "flex items-center gap-2 text-sm mb-4" do %>
|
28
|
+
<%= check_box_tag "default_billing", "true", true, class: 'input-checkbox' %>
|
29
|
+
<%= Spree.t('address_book.set_as_default_billing_address') %>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
<div class="border-t border-default px-8 py-4 flex justify-end gap-8 shrink-0">
|
33
|
+
<%= button_tag Spree.t(:cancel), class: 'uppercase text-sm font-semibold', data: { action: 'click->modal#close' } %>
|
34
|
+
<%= hidden_field_tag :from_modal, "true" %>
|
35
|
+
<%= f.submit Spree.t(:add), class: 'btn-primary w-48', data: { test_id: 'add-address-button' } %>
|
36
|
+
</div>
|
37
|
+
<% end %>
|
38
|
+
</div>
|
@@ -12,14 +12,34 @@
|
|
12
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 %>
|
13
13
|
</ul>
|
14
14
|
<div class="flex">
|
15
|
-
|
15
|
+
<div data-controller="modal" data-modal-allow-background-close="true">
|
16
|
+
<%= button_tag Spree.t(:add), type: "button", class: "btn-primary block w-full lg:w-auto", data: { action: "click->modal#open" } %>
|
17
|
+
<%= turbo_frame_tag :new_address_modal,
|
18
|
+
src: spree.new_address_path,
|
19
|
+
loading: :lazy,
|
20
|
+
data: {
|
21
|
+
modal_target: "container",
|
22
|
+
action: "click->modal#closeBackground keyup@window->modal#closeWithKeyboard"
|
23
|
+
},
|
24
|
+
class: "hidden animated fadeIn fixed inset-0 overflow-y-auto flex items-center justify-center z-[9999]" %>
|
25
|
+
</div>
|
16
26
|
</div>
|
17
27
|
<% else %>
|
18
28
|
<div class="text-center py-6">
|
19
29
|
<p class="mb-2 font-medium uppercase"><%= Spree.t('storefront.account.no_addresses_title') %></p>
|
20
30
|
<p><%= Spree.t('storefront.account.no_addresses_description') %></p>
|
21
31
|
<div class="flex mt-8 justify-center">
|
22
|
-
|
32
|
+
<div data-controller="modal" data-modal-allow-background-close="true">
|
33
|
+
<%= button_tag Spree.t(:add), type: "button", class: "btn-primary block", data: { action: "click->modal#open" } %>
|
34
|
+
<%= turbo_frame_tag :new_address_modal,
|
35
|
+
src: spree.new_address_path,
|
36
|
+
loading: :lazy,
|
37
|
+
data: {
|
38
|
+
modal_target: "container",
|
39
|
+
action: "click->modal#closeBackground keyup@window->modal#closeWithKeyboard"
|
40
|
+
},
|
41
|
+
class: "hidden animated fadeIn fixed inset-0 overflow-y-auto flex items-center justify-center z-[9999]" %>
|
42
|
+
</div>
|
23
43
|
</div>
|
24
44
|
</div>
|
25
45
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="flex items-center">
|
2
2
|
<%= form_for line_item, url: spree.line_item_url(line_item, order_token: line_item.order.token), data: { controller: 'turbo-stream-form' } do |item_form| %>
|
3
|
-
<div class="quantity-picker" data-controller="quantity-picker">
|
3
|
+
<div class="quantity-picker" data-controller="quantity-picker" data-quantity-picker-disabled-class="opacity-50 cursor-not-allowed">
|
4
4
|
<!-- this is a dummy button to work with turbo frame forms when hitting ENTER -->
|
5
5
|
<%= button_tag render('spree/shared/icons/minus'), type: 'submit', class: 'hidden' %>
|
6
6
|
<%= quantity_modifier_button_tag render('spree/shared/icons/minus'), type: 'submit', action: 'decrease', class: 'quantity-decrease-button' %>
|