Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SolidusAdmin customer picker for order #5462

Merged
merged 12 commits into from
Nov 13, 2023
145 changes: 76 additions & 69 deletions admin/app/components/solidus_admin/orders/cart/component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,84 @@
data-controller="<%= stimulus_id %>"
data-<%= stimulus_id %>-products-url-value="<%= solidus_admin.variants_for_order_path(@order) %>"
data-action="
<%= component('ui/search_panel').stimulus_id %>:search-><%= stimulus_id %>#search
<%= component('ui/search_panel').stimulus_id %>:submit-><%= stimulus_id %>#selectResult
<%= component('ui/forms/search').stimulus_id %>:search-><%= stimulus_id %>#search
<%= component('ui/forms/search').stimulus_id %>:submit-><%= stimulus_id %>#selectResult
"
>
<%= render component('ui/search_panel').new(
title: t('.title'),
search_placeholder: t('.search_placeholder'),
id: :order_cart,
) do |panel| %>
<table class="table-auto w-full" <%= :hidden if @order.line_items.empty? %>>
<thead>
<tr class="border-gray-100 border-t">
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none">Product</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16">Quantity</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16">Price</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
<% @order.line_items.each do |line_item| %>
<tr class="border-gray-100 border-t">
<td class="px-6 py-4">
<div class="flex gap-2 grow">
<% variant = line_item.variant %>
<%= render component("ui/thumbnail").new(
src: (variant.images.first || variant.product.gallery.images.first)&.url(:small),
alt: variant.name
) %>
<div class="flex-col">
<div class="leading-5 text-black body-small-bold"><%= variant.name %></div>
<div class="leading-5 text-gray-500 body-small">
SKU: <%= variant.sku %>
<%= variant.options_text.presence&.prepend("- ") %>
<%= render component('ui/panel').new(title: t('.title')) do |panel| %>
<% panel.with_section do %>
<%= render component('ui/forms/search').new(
placeholder: t('.search_placeholder'),
id: :order_cart,
) %>
<% end %>

<% panel.with_section(wide: true, high: true) do %>
<div class="rounded-b-lg overflow-hidden">
<table class="table-auto w-full" <%= :hidden if @order.line_items.empty? %>>
<thead>
<tr>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none">Product</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16">Quantity</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16">Price</th>
<th class="text-left body-small-bold text-gray-800 bg-gray-15 px-6 py-3 leading-none w-16"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
<% @order.line_items.each do |line_item| %>
<tr class="border-gray-100 border-t">
<td class="px-6 py-4">
<div class="flex gap-2 grow">
<% variant = line_item.variant %>
<%= render component("ui/thumbnail").new(
src: (variant.images.first || variant.product.gallery.images.first)&.url(:small),
alt: variant.name
) %>
<div class="flex-col">
<div class="leading-5 text-black body-small-bold"><%= variant.name %></div>
<div class="leading-5 text-gray-500 body-small">
SKU: <%= variant.sku %>
<%= variant.options_text.presence&.prepend("- ") %>
</div>
</div>
</div>
</div>
</div>
</td>
<td class="px-6 py-4">
<%= form_for(line_item, url: solidus_admin.order_line_item_path(@order, line_item), html: {
"data-controller": "readonly-when-submitting"
}) do |f| %>
<%= render component("ui/forms/input").new(
name: "#{f.object_name}[quantity]",
type: :number,
value: line_item.quantity,
"aria-label": "Quantity",
min: 0,
class: "!w-16 inline-block",
"data-action": "input->#{stimulus_id}#updateLineItem",
) %>
<% render component("ui/button").new(type: :submit, text: "Update", class: "inline-block") %>
<% end %>
</td>
<td class="px-6 py-4">
<span class="text-gray-500 body-small"><%= line_item.single_money.to_html %></span>
</td>
<td class="px-6 py-4 text-right">
<%= form_for(line_item, url: solidus_admin.order_line_item_path(@order, line_item), method: :delete) do |f| %>
<%= render component('ui/button').new(
scheme: :ghost,
size: :s,
title: t("spree.delete"),
icon: 'close-line',
"data-controller": "confirm",
"data-confirm-text-value": t("spree.are_you_sure"),
) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</td>
<td class="px-6 py-4">
<%= form_for(line_item, url: solidus_admin.order_line_item_path(@order, line_item), html: {
"data-controller": "readonly-when-submitting"
}) do |f| %>
<%= render component("ui/forms/input").new(
name: "#{f.object_name}[quantity]",
type: :number,
value: line_item.quantity,
"aria-label": "Quantity",
min: 0,
class: "!w-16 inline-block",
"data-action": "input->#{stimulus_id}#updateLineItem",
) %>
<% render component("ui/button").new(type: :submit, text: "Update", class: "inline-block") %>
<% end %>
</td>
<td class="px-6 py-4">
<span class="text-gray-500 body-small"><%= line_item.single_money.to_html %></span>
</td>
<td class="px-6 py-4 text-right">
<%= form_for(line_item, url: solidus_admin.order_line_item_path(@order, line_item), method: :delete) do |f| %>
<%= render component('ui/button').new(
scheme: :ghost,
size: :s,
title: t("spree.delete"),
icon: 'close-line',
"data-controller": "confirm",
"data-confirm-text-value": t("spree.are_you_sure"),
) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% end %>
<% end %>
</div>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= render component('ui/search_panel/result').new do %>
<%= render component('ui/forms/search/result').new do %>
<%= form_for(@order.line_items.build(variant: @variant), url: solidus_admin.order_line_items_path(@order), method: :post, html: {
"data-controller": "readonly-when-submitting",
class: "flex items-center",
Expand Down
64 changes: 32 additions & 32 deletions admin/app/components/solidus_admin/orders/show/component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,60 @@
<% end %>

<%= page_with_sidebar_aside do %>
<%= render component('ui/panel').new(title: panel_title_with_more_links(t(".customer"), [
link_to(t(".edit_email"), solidus_admin.order_customer_path(@order), class: "p-2 hover:bg-gray-25 rounded-sm text-black"),
link_to(t(".edit_shipping"), solidus_admin.new_order_ship_address_path(@order), class: "p-2 hover:bg-gray-25 rounded-sm text-black"),
link_to(t(".edit_billing"), solidus_admin.new_order_bill_address_path(@order), class: "p-2 hover:bg-gray-25 rounded-sm text-black"),
link_to(t(".remove_customer"), solidus_admin.order_customer_path(@order), 'data-turbo-method': :delete, class: "p-2 hover:bg-gray-25 rounded-sm text-red-500"),
])) do %>
<div class="flex flex-col -m-6 p-6 gap-6 border-t border-gray-100 mt-0">
<%# CUSTOMER %>
<% if @order.user %>
<div class="flex flex-col gap-2">
<div class="body-small-bold"><%= customer_name(@order.user) || tag.span(t('.no_name'), class: "text-gray-500") %></div>
<%= render component('ui/panel').new do |panel| %>
<% panel.with_menu t(".edit_email"), solidus_admin.order_customer_path(@order) %>
<% panel.with_menu t(".edit_shipping"), solidus_admin.new_order_ship_address_path(@order) %>
<% panel.with_menu t(".edit_billing"), solidus_admin.new_order_bill_address_path(@order) %>
<% panel.with_menu t(".remove_customer"), solidus_admin.order_customer_path(@order), method: :delete, class: "text-red-500" if @order.user %>

<% panel.with_section(class: 'flex flex-col gap-6') do %>
<div class="flex flex-col gap-2">
<span class="body-small-bold"><%= t(".customer") %></span>
<% if @order.user %>
<div class="body-small"><%= customer_name(@order.user) || tag.span(t('.no_name'), class: "text-gray-500") %></div>
<div class="body-small body-link"><%= link_to @order.user.email, spree.admin_user_path(@order.user) %></div>
<div class="body-small text-gray-500"><%= t(".orders_count", count: @order.user.orders.count) %></div>
</div>
<% end %>
<div class="body-small text-gray-500"><%= t(".orders_count", count: @order.user.orders.complete.count) %></div>
<% else %>
<%= render component('orders/show/customer_search').new(order: @order) %>
<% end %>
</div>

<%# EMAIL %>
<% if @order.email %>
<div class="flex flex-col gap-2">
<span class="body-small-bold"><%= t('.order_email') %></span>
<div class="body-small"><%= @order.email %></div>
<div class="flex flex-col gap-2">
<span class="body-small-bold"><%= t('.order_email') %></span>
<div class="body-small">
<% if @order.email? %>
<%= @order.email %>
<% else %>
<%= link_to(t(".add_email"), solidus_admin.order_customer_path(@order), class: "body-link") %>
<% end %>
</div>
<% end %>
</div>

<%# SHIPPING %>
<div class="flex flex-col gap-2">
<span class="body-small-bold"><%= @order.class.human_attribute_name(:ship_address) %></span>
<div class="body-small">
<% if @order.ship_address %>
<%= format_address @order.ship_address %>
<% else %>
<span class="italic text-gray-500"><%= t('.no_shipping_address') %></span>
<%= link_to t(".add_shipping"), solidus_admin.new_order_ship_address_path(@order), class: 'body-link' %>
<% end %>
</div>
</div>

<%# BILLING %>
<div class="flex flex-col gap-2">
<span class="body-small-bold"><%= @order.class.human_attribute_name(:bill_address) %></span>
<div class="body-small">
<% if @order.bill_address %>
<% if @order.bill_address == @order.ship_address %>
<span class="text-gray-500"><%= t('.same_as_shipping') %></span>
<% else %>
<%= format_address @order.bill_address %>
<% end %>
<% if @order.bill_address.blank? %>
<%= link_to t(".add_billing"), solidus_admin.new_order_bill_address_path(@order), class: 'body-link' %>
<% elsif @order.bill_address == @order.ship_address %>
<span class="text-gray-500"><%= t('.same_as_shipping') %></span>
<% else %>
<span class="italic text-gray-500"><%= t('.no_billing_address') %></span>
<%= format_address @order.bill_address %>
<% end %>
</div>
</div>

</div>

<% end %>
<% end %>

<% end %>
Expand Down
21 changes: 0 additions & 21 deletions admin/app/components/solidus_admin/orders/show/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,6 @@ def format_address(address)
], " ")
end

def panel_title_with_more_links(title, links)
tag.details(
tag.summary(
tag.span(
safe_join([
title,
component("ui/button").new(
icon: "more-line",
scheme: :ghost,
tag: :span,
alt: t("spree.edit"),
class: "cursor-pointer"
).render_in(self),
]),
class: 'flex items-center justify-between text-black',
)
) + tag.div(safe_join(links, " "), class: "body-small absolute border border-gray-100 mt-0.5 right-0 flex min-w-[10rem] flex-col p-2 rounded-sm shadow-lg bg-white z-10"),
class: 'relative',
)
end

def customer_name(user)
(
user.default_user_bill_address ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ en:
customer: Customer
no_name: No name available
order_email: Order contact email
no_billing_address: No billing address
no_shipping_address: No shipping address
same_as_shipping: Same as shipping address

edit_email: "Edit order email"
add_email: "Add order email"
edit_shipping: "Edit shipping address"
add_shipping: "Add shipping address"
edit_billing: "Edit billing address"
add_billing: "Add billing address"
remove_customer: "Remove customer"

orders_count:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div
class="w-full relative overflow-visible"
data-controller="<%= stimulus_id %>"
data-<%= stimulus_id %>-customers-url-value="<%= solidus_admin.customers_for_order_path(@order) %>"
data-action="
<%= component('ui/forms/search').stimulus_id %>:search-><%= stimulus_id %>#search
<%= component('ui/forms/search').stimulus_id %>:submit-><%= stimulus_id %>#submit
"
>
<%= render component("ui/forms/search").new(
placeholder: t(".placeholder"),
id: :order_customer
) %>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
static values = { customersUrl: String }

async search({ detail: { query, controller } }) {
controller.resultsValue =
(await (await fetch(`${this.customersUrlValue}?q[name_or_variants_including_master_sku_cont]=${query}`)).text())
}

submit(event) {
event.detail.resultTarget.querySelector('form').submit()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class SolidusAdmin::Orders::Show::CustomerSearch::Component < SolidusAdmin::BaseComponent
def initialize(order:)
@order = order
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
en:
placeholder: "Search customer"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%= render component('ui/forms/search/result').new do %>
<% if @customer %>
<%= form_for(@order, url: solidus_admin.order_path(@order), html: {
"data-controller": "readonly-when-submitting",
class: "flex items-center",
}) do |f| %>
<%= hidden_field_tag("#{f.object_name}[user_id]", @customer.id) %>
<button type="submit" class="flex gap-2 grow items-center">
<%= render component("ui/icon").new(name: "user-line", class: 'w-5 h-5 m-2') %>
<div class="flex-col text-left">
<div class="leading-5 text-black body-small-bold"><%= @name %></div>
<div class="leading-5 text-gray-500 body-small"><%= @customer.email %></div>
</div>
</button>
<% end %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class SolidusAdmin::Orders::Show::CustomerSearch::Result::Component < SolidusAdmin::BaseComponent
with_collection_parameter :customer

Check warning on line 4 in admin/app/components/solidus_admin/orders/show/customer_search/result/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/customer_search/result/component.rb#L3-L4

Added lines #L3 - L4 were not covered by tests

def initialize(order:, customer:)
@order = order
@customer = customer
@name = (customer.default_user_bill_address || customer.default_user_ship_address)&.address&.name if customer
end
end

Check warning on line 11 in admin/app/components/solidus_admin/orders/show/customer_search/result/component.rb

View check run for this annotation

Codecov / codecov/patch

admin/app/components/solidus_admin/orders/show/customer_search/result/component.rb#L6-L11

Added lines #L6 - L11 were not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<%= render component("ui/forms/field").text_field(f, :email) %>
<label class="body-small mt-4 block">
<%= t('.guest_checkout') %>:
<output class="body-small-bold"><%= @order.user ? t('.yes') : t('.no') %></output>
<output class="body-small-bold"><%= @order.user ? t('.no') : t('.yes') %></output>
<%= render component('ui/toggletip').new(text: t('.guest_checkout_tip'), class: "align-middle") %>
</label>
<% end %>
Expand Down
Loading
Loading