<% if @order.bill_address.blank? %>
- <%= link_to t(".add_billing"), solidus_admin.new_order_bill_address_path(@order), class: 'body-link' %>
+ <%= link_to t(".add_billing"), solidus_admin.edit_order_bill_address_path(@order), class: 'body-link' %>
<% elsif @order.bill_address == @order.ship_address %>
<%= t('.same_as_shipping') %>
<% else %>
diff --git a/admin/app/components/solidus_admin/ui/forms/address/component.html.erb b/admin/app/components/solidus_admin/ui/forms/address/component.html.erb
index e4c66ad6057..3567418ffb1 100644
--- a/admin/app/components/solidus_admin/ui/forms/address/component.html.erb
+++ b/admin/app/components/solidus_admin/ui/forms/address/component.html.erb
@@ -3,32 +3,34 @@
<%= :disabled if @disabled %>
>
- <%= render component("ui/forms/field").text_field(@form, :name) %>
- <%= render component("ui/forms/field").text_field(@form, :address1) %>
- <%= render component("ui/forms/field").text_field(@form, :address2) %>
+ <%= render component("ui/forms/field").text_field(@name, :name, object: @address) %>
+ <%= render component("ui/forms/field").text_field(@name, :address1, object: @address) %>
+ <%= render component("ui/forms/field").text_field(@name, :address2, object: @address) %>
- <%= render component("ui/forms/field").text_field(@form, :city) %>
- <%= render component("ui/forms/field").text_field(@form, :zipcode) %>
+ <%= render component("ui/forms/field").text_field(@name, :city, object: @address) %>
+ <%= render component("ui/forms/field").text_field(@name, :zipcode, object: @address) %>
<%= render component("ui/forms/field").select(
- @form,
+ @name,
:country_id,
Spree::Country.all.map { |c| [c.name, c.id] },
- value: @form.object.try(:country_id),
+ object: @address,
+ value: @address.try(:country_id),
"data-#{stimulus_id}-target": "country",
"data-action": "change->#{stimulus_id}#loadStates"
) %>
<%= render component("ui/forms/field").select(
- @form,
+ @name,
:state_id,
state_options,
- value: @form.object.try(:state_id),
- disabled: @form.object.country&.states&.empty?,
+ object: @address,
+ value: @address.try(:state_id),
+ disabled: @address.country&.states&.empty?,
"data-#{stimulus_id}-target": "state"
) %>
- <%= render component("ui/forms/field").text_field(@form, :phone) %>
+ <%= render component("ui/forms/field").text_field(@name, :phone, object: @address) %>
diff --git a/admin/app/components/solidus_admin/ui/forms/address/component.rb b/admin/app/components/solidus_admin/ui/forms/address/component.rb
index 5aa67048967..fffe19e6d3a 100644
--- a/admin/app/components/solidus_admin/ui/forms/address/component.rb
+++ b/admin/app/components/solidus_admin/ui/forms/address/component.rb
@@ -1,13 +1,14 @@
# frozen_string_literal: true
class SolidusAdmin::UI::Forms::Address::Component < SolidusAdmin::BaseComponent
- def initialize(form:, disabled: false)
- @form = form
+ def initialize(address:, name:, disabled: false)
+ @address = address
+ @name = name
@disabled = disabled
end
def state_options
- return [] unless @form.object.country
- @form.object.country.states.map { |s| [s.name, s.id] }
+ return [] unless @address.country
+ @address.country.states.map { |s| [s.name, s.id] }
end
end
diff --git a/admin/app/components/solidus_admin/ui/forms/field/component.rb b/admin/app/components/solidus_admin/ui/forms/field/component.rb
index b66c7cc1a97..a2bb0b300a1 100644
--- a/admin/app/components/solidus_admin/ui/forms/field/component.rb
+++ b/admin/app/components/solidus_admin/ui/forms/field/component.rb
@@ -12,61 +12,78 @@ def initialize(label:, hint: nil, tip: nil, error: nil, input_attributes: nil, *
raise ArgumentError, "provide either a block or input_attributes" if content? && input_attributes
end
- def self.text_field(form, method, hint: nil, tip: nil, size: :m, **attributes)
- errors = form.object.errors.messages_for(method).presence
+ def self.text_field(form, method, object: nil, hint: nil, tip: nil, size: :m, **attributes)
+ object_name, object, label, errors = extract_form_details(form, object, method)
new(
- label: form.object.class.human_attribute_name(method),
+ label: label,
hint: hint,
tip: tip,
error: errors,
input_attributes: {
- name: "#{form.object_name}[#{method}]",
+ name: "#{object_name}[#{method}]",
tag: :input,
size: size,
- value: form.object.public_send(method),
+ value: object.public_send(method),
error: (errors.to_sentence.capitalize if errors),
**attributes,
}
)
end
- def self.select(form, method, choices, hint: nil, tip: nil, size: :m, **attributes)
- errors = form.object.errors.messages_for(method).presence
+ def self.select(form, method, choices, object: nil, hint: nil, tip: nil, size: :m, **attributes)
+ object_name, object, label, errors = extract_form_details(form, object, method)
new(
- label: form.object.class.human_attribute_name(method),
+ label: label,
hint: hint,
tip: tip,
error: errors,
input_attributes: {
- name: "#{form.object_name}[#{method}]",
+ name: "#{object_name}[#{method}]",
tag: :select,
choices: choices,
size: size,
- value: form.object.public_send(method),
+ value: object.public_send(method),
error: (errors.to_sentence.capitalize if errors),
**attributes,
}
)
end
- def self.text_area(form, method, hint: nil, tip: nil, size: :m, **attributes)
- errors = form.object.errors.messages_for(method).presence
+ def self.text_area(form, method, object: nil, hint: nil, tip: nil, size: :m, **attributes)
+ object_name, object, label, errors = extract_form_details(form, object, method)
new(
- label: form.object.class.human_attribute_name(method),
+ label: label,
hint: hint,
tip: tip,
error: errors,
input_attributes: {
- name: "#{form.object_name}[#{method}]",
+ name: "#{object_name}[#{method}]",
size: size,
tag: :textarea,
- value: form.object.public_send(method),
+ value: object.public_send(method),
error: (errors.to_sentence.capitalize if errors),
**attributes,
}
)
end
+
+ def self.extract_form_details(form, object, method)
+ if form.is_a?(String)
+ object_name = form
+ raise ArgumentError, "Object must be provided when form name is a string" unless object
+ elsif form.respond_to?(:object)
+ object_name = form.object_name
+ object = form.object
+ else
+ raise ArgumentError, "Invalid arguments: expected a form object or form.object_name and form.object"
+ end
+
+ errors = object.errors.messages_for(method).presence if object.respond_to?(:errors)
+ label = object.class.human_attribute_name(method)
+
+ [object_name, object, label, errors]
+ end
end
diff --git a/admin/app/controllers/solidus_admin/addresses_controller.rb b/admin/app/controllers/solidus_admin/addresses_controller.rb
index 8cbb7bfd3e2..83a8da3a91e 100644
--- a/admin/app/controllers/solidus_admin/addresses_controller.rb
+++ b/admin/app/controllers/solidus_admin/addresses_controller.rb
@@ -7,17 +7,25 @@ class AddressesController < BaseController
before_action :load_order
before_action :validate_address_type
- def new
- address = @order.send("#{address_type}_address")
- @order.send("build_#{address_type}_address", country_id: default_country_id) if address.nil?
- address ||= @order.send("#{address_type}_address")
- address.country_id ||= default_country_id if address.country.nil?
+ def show
+ address = find_address || build_new_address
respond_to do |format|
- format.html { render component('orders/show/address').new(order: @order, type: address_type) }
+ format.html do
+ render component('orders/show/address').new(
+ order: @order,
+ user: @order.user,
+ address: address,
+ type: address_type,
+ )
+ end
end
end
+ def edit
+ redirect_to action: :show
+ end
+
def update
if @order.contents.update_cart(order_params)
redirect_to order_path(@order), status: :see_other, notice: t('.success')
@@ -25,13 +33,36 @@ def update
flash.now[:error] = @order.errors[:base].join(", ") if @order.errors[:base].any?
respond_to do |format|
- format.html { render component('orders/show/address').new(order: @order, type: address_type), status: :unprocessable_entity }
+ format.html do
+ render component('orders/show/address').new(
+ order: @order,
+ user: @order.user,
+ address: @order.send("#{address_type}_address"),
+ type: address_type,
+ status: :unprocessable_entity,
+ )
+ end
end
end
end
private
+ def find_address
+ if params[:address_id].present? && @order.user
+ address = @order.user.addresses.find_by(id: params[:address_id])
+ @order.send("#{address_type}_address=", address) if address
+ else
+ @order.send("#{address_type}_address")
+ end
+ end
+
+ def build_new_address
+ @order.send("build_#{address_type}_address", country_id: default_country_id).tap do |address|
+ address.country_id ||= default_country_id if address.country.nil?
+ end
+ end
+
def address_type
params[:type].presence_in(%w[bill ship])
end
diff --git a/admin/config/routes.rb b/admin/config/routes.rb
index d0c3a997fa9..6b45f676195 100644
--- a/admin/config/routes.rb
+++ b/admin/config/routes.rb
@@ -21,8 +21,8 @@
resources :orders, only: [:index, :show, :edit, :update] do
resources :line_items, only: [:destroy, :create, :update]
resource :customer
- resource :ship_address, only: [:new, :update], controller: "addresses", type: "ship"
- resource :bill_address, only: [:new, :update], controller: "addresses", type: "bill"
+ resource :ship_address, only: [:show, :edit, :update], controller: "addresses", type: "ship"
+ resource :bill_address, only: [:show, :edit, :update], controller: "addresses", type: "bill"
member do
get :variants_for
diff --git a/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview.rb b/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview.rb
index 2120f317a95..4279afad087 100644
--- a/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview.rb
+++ b/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview.rb
@@ -11,6 +11,7 @@ def overview
render_with_template(
locals: {
order: order,
+ address: order.send("#{type}_address"),
type: type
}
)
@@ -19,7 +20,7 @@ def overview
# @param type select :type_options
def playground(type: "ship")
order = fake_order(type)
- render current_component.new(order: order, type: type)
+ render current_component.new(order: order, address: order.send("#{type}_address"), type: type)
end
private
diff --git a/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview/overview.html.erb
index 1f2f4e68235..a5b1b6ac203 100644
--- a/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview/overview.html.erb
+++ b/admin/spec/components/previews/solidus_admin/orders/show/address/component_preview/overview.html.erb
@@ -1 +1 @@
-<%= render current_component.new(order: order, type: type) %>
+<%= render current_component.new(order: order, address: address, type: type) %>
diff --git a/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview.rb b/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview.rb
index e3bd6a00526..cba6252cd1b 100644
--- a/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview.rb
+++ b/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview.rb
@@ -5,15 +5,22 @@ class SolidusAdmin::UI::Forms::Address::ComponentPreview < ViewComponent::Previe
include SolidusAdmin::Preview
def overview
- render_with_template
+ render_with_template(locals: { address: fake_address })
end
# @param disabled toggle
def playground(disabled: false)
- view = ActionView::Base.new(ActionView::LookupContext.new([]), {}, nil)
render component("ui/forms/address").new(
- form: ActionView::Helpers::FormBuilder.new(:address, Spree::Address.new, view, {}),
+ name: "",
+ address: fake_address,
disabled: disabled
)
end
+
+ private
+
+ def fake_address
+ country = Spree::Country.find_or_initialize_by(iso: Spree::Config.default_country_iso)
+ Spree::Address.new(country: country)
+ end
end
diff --git a/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview/overview.html.erb
index 8068d4ec9b7..057e6ed9a3f 100644
--- a/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview/overview.html.erb
+++ b/admin/spec/components/previews/solidus_admin/ui/forms/address/component_preview/overview.html.erb
@@ -1,3 +1 @@
-<%= form_for Spree::Address.new, url: '#' do |f| %>
- <%= render current_component.new(form: f, disabled: false) %>
-<% end %>
+<%= render current_component.new(name: "", address: address) %>