diff --git a/admin/app/components/solidus_admin/orders/address/component.html.erb b/admin/app/components/solidus_admin/orders/address/component.html.erb new file mode 100644 index 00000000000..4fdbdd16055 --- /dev/null +++ b/admin/app/components/solidus_admin/orders/address/component.html.erb @@ -0,0 +1,56 @@ +
+ <%= page do %> + <%= page_header do %> + <%= page_header_back(solidus_admin.edit_order_path(@order)) %> + <%= page_header_title(t(".title", address: t(".#{@type}_address"))) %> + <%= page_header_actions do %> + <%= render component("ui/button").new( + tag: :a, + scheme: :secondary, + text: t(".cancel"), + href: solidus_admin.edit_order_path(@order) + ) %> + + <%= render component("ui/button").new( + tag: :button, + text: t(".save"), + form: form_id + ) %> + <% end %> + <% end %> + + <%= page_with_sidebar do %> + <%= page_with_sidebar_main do %> + <%= render component('ui/panel').new do %> + <%= form_for @order, url: solidus_admin.send("order_#{@type}_address_path", @order), html: { id: form_id } do |f| %> +
+

<%= t(".#{@type}_address") %>

+
+ <%= f.fields_for :"#{@type}_address" do |form| %> + <%= render component('ui/forms/address').new(form: form, disabled: false) %> + <% end %> +
+
+ <% end %> + <% end %> + <% end %> + <% end %> + + <%= page_footer do %> + <%= page_footer_actions do %> + <%= render component("ui/button").new( + tag: :a, + scheme: :secondary, + text: t(".cancel"), + href: solidus_admin.edit_order_path(@order) + ) %> + + <%= render component("ui/button").new( + tag: :button, + text: t(".save"), + form: form_id + ) %> + <% end %> + <% end %> + <% end %> +
diff --git a/admin/app/components/solidus_admin/orders/address/component.js b/admin/app/components/solidus_admin/orders/address/component.js new file mode 100644 index 00000000000..b6e2b996c67 --- /dev/null +++ b/admin/app/components/solidus_admin/orders/address/component.js @@ -0,0 +1,14 @@ +import { Controller } from '@hotwired/stimulus' + +export default class extends Controller { + static targets = ['output'] + + typed(event) { + this.text = event.currentTarget.value + this.render() + } + + render() { + this.outputTarget.innerText = this.text + } +} diff --git a/admin/app/components/solidus_admin/orders/address/component.rb b/admin/app/components/solidus_admin/orders/address/component.rb new file mode 100644 index 00000000000..fdb40ce2f34 --- /dev/null +++ b/admin/app/components/solidus_admin/orders/address/component.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class SolidusAdmin::Orders::Address::Component < SolidusAdmin::BaseComponent + include SolidusAdmin::Layout::PageHelpers + + VALID_TYPES = ['ship', 'bill'].freeze + + def initialize(order:, type: "ship") + @order = order + @type = validate_address_type(type) + end + + def form_id + @form_id ||= "#{stimulus_id}--form-#{@type}-#{@order.id}" + end + + private + + def validate_address_type(type) + VALID_TYPES.include?(type) ? type : raise(ArgumentError, "Invalid address type: #{type}") + end +end diff --git a/admin/app/components/solidus_admin/orders/address/component.yml b/admin/app/components/solidus_admin/orders/address/component.yml new file mode 100644 index 00000000000..985a2145021 --- /dev/null +++ b/admin/app/components/solidus_admin/orders/address/component.yml @@ -0,0 +1,9 @@ +# Add your component translations here. +# Use the translation in the example in your template with `t(".hello")`. +en: + save: Save + cancel: Cancel + back: Back + title: "Edit %{address}" + ship_address: Shipping Address + bill_address: Billing Address diff --git a/admin/app/components/solidus_admin/orders/show/component.html.erb b/admin/app/components/solidus_admin/orders/show/component.html.erb index b6a553d56a5..9fad865480a 100644 --- a/admin/app/components/solidus_admin/orders/show/component.html.erb +++ b/admin/app/components/solidus_admin/orders/show/component.html.erb @@ -16,8 +16,8 @@ <%= page_with_sidebar_aside do %> <%= render component('ui/panel').new(title: panel_title_with_more_links(t(".customer"), [ link_to("Edit order email", "#", class: "p-2 hover:bg-gray-25 rounded-sm text-black"), - link_to("Edit shipping address", "#", class: "p-2 hover:bg-gray-25 rounded-sm text-black"), - link_to("Edit billing address", "#", class: "p-2 hover:bg-gray-25 rounded-sm text-black"), + link_to("Edit shipping address", solidus_admin.new_order_ship_address_path(@order), class: "p-2 hover:bg-gray-25 rounded-sm text-black"), + link_to("Edit billing address", solidus_admin.new_order_bill_address_path(@order), class: "p-2 hover:bg-gray-25 rounded-sm text-black"), link_to("Remove customer", "#", 'data-turbo-method': :delete, class: "p-2 hover:bg-gray-25 rounded-sm text-red-500"), ])) do %>
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 f13f88284cf..b791c7ad7b8 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 @@ -6,9 +6,9 @@ <%= 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(@form, :city, class: "flex-1") %> - <%= render component("ui/forms/field").text_field(@form, :zipcode, class: "flex-1") %> +
+ <%= render component("ui/forms/field").text_field(@form, :city) %> + <%= render component("ui/forms/field").text_field(@form, :zipcode) %>
<%= render component("ui/forms/field").select( diff --git a/admin/app/controllers/solidus_admin/addresses_controller.rb b/admin/app/controllers/solidus_admin/addresses_controller.rb new file mode 100644 index 00000000000..1b527b86ff5 --- /dev/null +++ b/admin/app/controllers/solidus_admin/addresses_controller.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module SolidusAdmin + class AddressesController < BaseController + include Spree::Core::ControllerHelpers::StrongParameters + + 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? + + respond_to do |format| + format.html { render component('orders/address').new(order: @order, type: address_type) } + end + end + + def update + if @order.contents.update_cart(order_params) + flash[:success] = t('spree.customer_details_updated') + redirect_to edit_order_url(@order) + else + respond_to do |format| + format.html { render component('orders/address').new(order: @order, type: address_type) } + end + end + end + + private + + def address_type + params[:address_type].presence_in(%w[bill ship]) + end + + def validate_address_type + unless address_type + flash[:error] = t('spree.address_type_invalid') + redirect_to spree.admin_order_url(@order) + end + end + + def default_country_id + @default_country_id ||= begin + country = Spree::Country.default + country.id if Spree::Country.available.exists?(id: country.id) + end + end + + def load_order + @order = Spree::Order.find_by!(number: params[:order_id]) + authorize! action_name, @order + end + + def order_params + params.require(:order).permit( + bill_address_attributes: permitted_address_attributes, + ship_address_attributes: permitted_address_attributes + ) + end + end +end diff --git a/admin/config/routes.rb b/admin/config/routes.rb index 98db04921c4..a1493f2569a 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -20,6 +20,8 @@ resources :orders, only: [:index, :show, :edit] do resources :line_items, only: [:destroy, :create, :update] + resource :ship_address, only: [:new, :update], controller: "addresses", address_type: "ship" + resource :bill_address, only: [:new, :update], controller: "addresses", address_type: "bill" member do get :variants_for diff --git a/admin/spec/components/previews/solidus_admin/orders/address/component_preview.rb b/admin/spec/components/previews/solidus_admin/orders/address/component_preview.rb new file mode 100644 index 00000000000..d913c5c7bf7 --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/orders/address/component_preview.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# @component "orders/address" +class SolidusAdmin::Orders::Address::ComponentPreview < ViewComponent::Preview + include SolidusAdmin::Preview + + def overview + render_with_template + end + + # @param address text + # @param type text + def playground(address: "address", type: "type") + render component("orders/address").new(address: address, type: type) + end +end diff --git a/admin/spec/components/previews/solidus_admin/orders/address/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/orders/address/component_preview/overview.html.erb new file mode 100644 index 00000000000..1a3d5ffadb0 --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/orders/address/component_preview/overview.html.erb @@ -0,0 +1,7 @@ +
+
+ Scenario 1 +
+ + <%= render current_component.new(address: "address", type: "type") %> +
diff --git a/admin/spec/components/solidus_admin/orders/address/component_spec.rb b/admin/spec/components/solidus_admin/orders/address/component_spec.rb new file mode 100644 index 00000000000..ab1387decac --- /dev/null +++ b/admin/spec/components/solidus_admin/orders/address/component_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe SolidusAdmin::Orders::Address::Component, type: :component do + it "renders the overview preview" do + render_preview(:overview) + end + + # it "renders something useful" do + # render_inline(described_class.new(address: "address", type: "type")) + # + # expect(page).to have_text "Hello, components!" + # expect(page).to have_css '.value' + # end +end