Merge pull request #10254 from jibees/10246-split-checkout-order-summary-page-design-changes

Split checkout: order summary page design changes
This commit is contained in:
Rachel Arnould
2023-01-23 15:52:06 +01:00
committed by GitHub
22 changed files with 336 additions and 235 deletions

View File

@@ -11,6 +11,7 @@ module CheckoutHelper
def checkout_adjustments_for(order, opts = {})
exclude = opts[:exclude] || {}
reject_zero_amount = opts.fetch(:reject_zero_amount, true)
adjustments = order.all_adjustments.eligible.to_a
@@ -32,6 +33,10 @@ module CheckoutHelper
}
end
if reject_zero_amount
adjustments.reject! { |a| a.amount == 0 }
end
adjustments
end

View File

@@ -9,7 +9,7 @@
= t :checkout_cart_total
%td.cart-total.text-right= display_checkout_subtotal(@order)
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).reject{ |a| a.amount == 0 }.each do |adjustment|
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).each do |adjustment|
%tr.adjustment
%th= adjustment.label
%td.text-right= adjustment.display_amount.to_html

View File

@@ -1,3 +1,3 @@
.already-ordered
.panel.medium-6
.panel
= t("split_checkout.already_ordered.message_html", cart: link_to(t('split_checkout.already_ordered.cart'), "#{main_app.cart_path}#bought-products"))

View File

@@ -1,5 +1,4 @@
%checkout.row#checkout
.small-12.medium-12.columns
= render partial: "split_checkout/tabs"
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
= render partial: "split_checkout/form"

View File

@@ -89,7 +89,7 @@
"data-action": "toggle#toggle shippingmethod#selectShippingMethod",
"data-toggle-show": shipping_method.require_ship_address
= shipping_method_form.label shipping_method.id, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
%em= payment_or_shipping_price(shipping_method, @order)
%em.fees= payment_or_shipping_price(shipping_method, @order)
- display_ship_address = display_ship_address || (ship_method_is_selected && shipping_method.require_ship_address)
%div.checkout-input{"data-shippingmethod-target": "shippingMethodDescription", "data-shippingmethodid": shipping_method.id , style: "display: #{ship_method_is_selected ? 'block' : 'none'}" }
#distributor_address.panel

View File

@@ -1,7 +1,7 @@
- content_for :injection_data do
= inject_saved_credit_cards
%div.checkout-step
%div.checkout-step{"class": if checkout_step?(:summary) then "checkout-summary" end}
= form_with url: checkout_update_path(checkout_step), model: @order, method: :put,
data: { remote: "true" } do |form|

View File

@@ -15,7 +15,7 @@
"data-paymentmethod-id": "paymentmethod#{payment_method.id}",
"data-paymentmethod-target": "input"
= f.label :payment_method_id, "#{payment_method.name}", for: "payment_method_#{payment_method.id}"
%em=payment_or_shipping_price(payment_method, @order)
%em.fees=payment_or_shipping_price(payment_method, @order)
.paymentmethod-container{"data-paymentmethod-id": "paymentmethod#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"}
- if payment_method.description && !payment_method.description.empty?

View File

@@ -1,81 +1,94 @@
.medium-10
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.your_details.title")
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.first_name.label")
%span.summary-value
= @order.bill_address.firstname
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.last_name.label")
%span.summary-value
= @order.bill_address.lastname
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.email.label")
%span.summary-value
= @order.user ? @order.user.email : "Change me"
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.phone.label")
%span.summary-value
= @order.bill_address.phone
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.billing_address.title")
= render "summary_address", address: @order.bill_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.shipping_address.title")
= render "summary_address", address: @order.shipping_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.delivery_info.title")
%div.summary
%span.summary-label
= t("split_checkout.step1.shipping_info.title")
%span.summary-value
= @order.shipping_method.name
%div.summary-description
= @order.shipping_method.description
.summary-main
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
.checkout-substep
.checkout-title
= t("split_checkout.step3.delivery_details.title")
%a.summary-edit{href: main_app.checkout_step_path(:details)}
= t("split_checkout.step3.your_details.edit")
= t("split_checkout.step3.delivery_details.edit")
%div.checkout-substep
%div.checkout-title
.summary-subtitle
= @order.shipping_method.name
%em.fees= payment_or_shipping_price(@order.shipping_method, @order)
.two-columns
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.address")
%span
= @order.bill_address.firstname
= @order.bill_address.lastname
%div
= @order.bill_address.phone
%div
= @order.user.email if @order.user
%br
%div
= @order.bill_address.address1
- unless @order.bill_address.address2.blank?
%div
= @order.bill_address.address2
%div
= @order.bill_address.city
%div
= @order.bill_address.state
%div
= @order.bill_address.zipcode
%div
= @order.bill_address.country
- if @order.shipping_method.description.present?
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.instructions")
%div
= @order.shipping_method.description
%hr
.checkout-substep
.checkout-title
= t("split_checkout.step3.payment_method.title")
%div.summary
%span.summary-value
= last_payment_method(@order)&.name
%div.summary-description
= last_payment_method(@order)&.description
%a.summary-edit{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.payment_method.edit")
.two-columns
%div
- payment_method = last_payment_method(@order)
= payment_method&.name
%em.fees=payment_or_shipping_price(payment_method, @order)
%div
.summary-subtitle
= t("split_checkout.step3.payment_method.instructions")
%div
= last_payment_method(@order)&.description
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.order.title")
%a.summary-edit{href: main_app.cart_path}
= t("split_checkout.step3.order.edit")
= render 'spree/orders/summary', order: @order
= render 'spree/orders/summary', order: @order, display_footer: false
.checkout-step3{"data-controller": "sticky", "data-sticky-target": "container"}
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
.medium-6
.checkout-submit
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
%a.button.cancel{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.cancel")
.summary-right{ "data-controller": "sticky", "data-sticky-target": "container" }
.summary-right-line.total
.summary-right-line-label= t :order_total_price
.summary-right-line-value#order_total= @order.display_total.to_html
.summary-right-line
.summary-right-line-label= t :order_produce
.summary-right-line-value= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
.summary-right-line
.summary-right-line-label= adjustment.label
.summary-right-line-value= adjustment.display_amount.to_html
- if @order.total_tax > 0
.summary-right-line
.summary-right-line-label= t :order_includes_tax
.summary-right-line-value#tax-row= display_checkout_tax_total(@order)
.checkout-submit
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false

View File

@@ -1,36 +0,0 @@
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address1.label")
%span.summary-value
= address.address1
- unless @order.bill_address.address2.blank?
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address2.label")
%span.summary-value
= address.address2
%div.summary
%span.summary-label
= t("split_checkout.step1.address.city.label")
%span.summary-value
= address.city
%div.summary
%span.summary-label
= t("split_checkout.step1.address.state_id.label")
%span.summary-value
= address.state
%div.summary
%span.summary-label
= t("split_checkout.step1.address.zipcode.label")
%span.summary-value
= address.zipcode
%div.summary
%span.summary-label
= t("split_checkout.step1.address.country_id.label")
%span.summary-value
= address.country

View File

@@ -1,4 +1,4 @@
%div.checkout-substep.medium-6
%div.checkout-substep
%div.checkout-input
- if platform_terms_required? && distributor_terms_required?
= f.check_box :accept_terms, { name: "accept_terms", checked: all_terms_and_conditions_already_accepted? }, 1, nil
@@ -14,6 +14,3 @@
= t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions, target: '_blank'))
= f.error_message_on :terms_and_conditions, standalone: true
%div.checkout-input
= t("split_checkout.step3.agree")

View File

@@ -24,7 +24,7 @@
%td{:align => "right"}
= item.display_amount_with_adjustments
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- taxable = adjustment.adjustable_type == "Spree::Shipment" ? adjustment.adjustable : adjustment
%tr
%td

View File

@@ -30,7 +30,7 @@
%td{:align => "right"}
= display_line_item_tax_rates(item)
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
%tr
%td
%strong= "#{raw(adjustment.label)}"

View File

@@ -43,7 +43,7 @@
j(line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false))] }
.join('" + \'\x0A\' + "')}",
'\x0A',
"#{checkout_adjustments_for(@order, exclude: [:line_item])
"#{checkout_adjustments_for(@order, exclude: [:line_item], reject_zero_amount: false)
.reject{ |a| a.amount == 0 }
.reverse.map { |adjustment| '%5s %-27.27s%8.8s' %
["",

View File

@@ -40,7 +40,7 @@
= t :email_order_summary_subtotal
%td{align: "right"}
= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
%tr
%td{align: "right", colspan: "3"}
= "#{raw(adjustment.label)}:"

View File

@@ -31,7 +31,7 @@
%span.order-total.item-total= display_checkout_subtotal(@order)
%td
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
%tr.order-adjustment
%td.text-right{:colspan => "3"}
= adjustment.label

View File

@@ -1,3 +1,5 @@
- display_footer = true if display_footer.nil?
%table#line-items{"data-hook" => "order_details"}
%col{valign: "middle"}/
%col{halign: "center", valign: "middle", width: "5%"}/
@@ -26,36 +28,4 @@
%td.text-right.total{"data-hook" => "order_item_total"}
%span= item.display_amount_with_adjustments.to_html
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)
= render partial: "spree/orders/totals_footer", locals: { order: order } if display_footer

View File

@@ -0,0 +1,33 @@
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)

View File

@@ -15,7 +15,7 @@ export default class extends Controller {
this.containerTarget.style.bottom = "-1px";
const observer = new IntersectionObserver(
([e]) => {
e.target.classList.toggle("sticked", e.intersectionRatio <= 1);
e.target.classList.toggle("sticked", e.intersectionRatio < 1);
},
{ threshold: [1] }
);

View File

@@ -62,8 +62,9 @@
}
.already-ordered {
margin-left: 20px;
.panel {
margin-top: 3rem;
background-color: $grey-250;
border: 1px solid $tiny-blue;
color: $grey-700;
@@ -160,22 +161,24 @@
label {
margin-top: 0.3rem;
& + em {
margin-left: -0.5rem;
font-size: 14px; // same as label
font-weight: bold;
// Add opening and closing parentheses
&:before {
content: "(";
}
&:after {
content: ")";
}
}
}
}
}
em.fees {
margin-left: -0.5rem;
font-size: 14px; // same as label
font-weight: bold;
margin-left: 10px;
// Add opening and closing parentheses
&:before {
content: "(";
}
&:after {
content: ")";
}
}
.checkout-input span.formError, div.error.card-errors {
background-color: rgba(193, 18, 43, 0.1);
color: $red-700;
@@ -203,42 +206,7 @@
@include force-wrap;
}
.checkout-step3 {
padding-left: 15px;
padding-right: 15px;
.checkout-submit {
margin-top: 0;
margin-bottom: 0;
padding-top: 2rem;
.button {
margin-bottom: 1rem;
}
}
&.sticked {
background-color: $white;
box-shadow: 0 -6px 12px -6px rgba(0, 0, 0, 0.33);
border-left: 1px solid $light-grey;
border-right: 1px solid $light-grey;
border-top: 1px solid $light-grey;
}
@media screen and (max-width: 700px) {
&.sticked {
width: auto;
margin-left: -15px;
margin-right: -15px;
box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.33);
.checkout-submit {
width: 100%;
padding-left: 15px;
padding-right: 15px;
}
}
}
}
.checkout-submit {
margin-top: 5rem;
@@ -291,24 +259,44 @@
}
}
.summary {
margin-bottom: 2px;
font-size: 0.875rem;
.checkout-summary {
margin-top: 0;
.summary-label {
font-weight: bold;
}
.checkout-substep {
font-size: 0.875rem;
margin-top: 1rem;
.summary-description {
@include force-wrap;
color: $min-accessible-grey;
&:first-child {
margin-top: 20px;
}
.two-columns {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 1fr;
grid-column-gap: 10px;
grid-row-gap: 0px;
}
}
.summary-edit {
color: $teal-400;
text-decoration: underline;
display: block;
margin-top: 5px;
display: inline-block;
margin-left: 15px;
font-size: 0.875rem;
font-weight: normal;
font-family: $body-font;
&:hover {
color: $teal-500;
text-decoration: underline;
&:after {
color: $teal-500;
}
}
&:after {
background-image: url("../images/edit-with-pen.svg");
content: " ";
@@ -321,11 +309,94 @@
top: 2px;
}
}
.summary-subtitle {
font-weight: bold;
margin-bottom: 20px;
}
}
.checkout-summary {
form {
display: flex;
justify-content: space-between;
.summary-main {
width: 66.66%;
border-right: 1px solid #DDD;
padding-right: 20px;
padding-top: 20px;
}
.summary-right {
width: calc(33.33% - 20px);
padding-left: 20px;
padding-right: 20px;
border-right: 1px solid #DDD;
}
}
}
.summary-right {
padding-top: 40px;
.checkout-submit {
margin-top: 40px;
.button.primary {
background-color: $clr-turquoise;
&:hover {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
}
}
}
.summary-right-line {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.summary-right-line-label {
font-size: 0.875rem;
}
.summary-right-line-value {
font-size: 0.875rem;
text-align: right;
}
&.total {
margin-bottom: 20px;
@include headingFont;
.summary-right-line-label {
font-weight: bold;
font-size: 1.06rem;
}
.summary-right-line-value {
font-size: 1.06rem;
}
}
}
.summary-right {
.checkout-input {
display: flex;
align-items: baseline;
input[type=checkbox] + label {
margin-left: 1rem;
}
}
}
#line-items {
display: block;
overflow-x: auto;
h5 {
background-color: transparent;
}
}
.two-columns-inputs {
@@ -381,3 +452,58 @@
}
}
}
// Handle the mobile view for the summary step
@media screen and (max-width: 800px) {
.checkout-summary form {
display: block;
}
.checkout-summary form .summary-right {
width: calc(100% + 30px);
margin-left: -15px;
background-color: white;
border-right: none;
border-top: 1px solid #DDD;
padding-top: 20px;
&.sticked {
box-shadow: 0 -4px 10px #DDD;
}
.summary-right-line.total {
margin-bottom: 10px;
}
.checkout-submit {
margin-top: 10px;
.checkout-input {
margin-bottom: 10px;
}
.button {
margin-bottom: 10px;
}
}
}
.checkout-summary form .summary-main {
width: 100%;
border-right: none;
}
.checkout-summary .checkout-substep .two-columns {
// only one column actually
grid-template-columns: 1fr;
> :nth-child(2) {
margin-top: 20px;
}
}
.checkout-summary .summary-subtitle {
margin-bottom: 10px;
}
}

View File

@@ -1973,20 +1973,18 @@ en:
submit: Next - Order summary
cancel: Back to Your details
step3:
your_details:
title: Your details
edit: Edit your details
billing_address:
title: Billing address
shipping_address:
title: Shipping address
delivery_info:
title: Delivery info
delivery_details:
title: Delivery details
edit: Edit
address: Delivery address
instructions: Instructions
payment_method:
title: Payment method
edit: Edit payment method
edit: Edit
instructions: Instructions
order:
title: Order total
title: Order details
edit: Edit
terms_and_conditions:
message_html: "I agree to the seller's %{terms_and_conditions_link}."
link_text: "Terms and Conditions"
@@ -1995,7 +1993,6 @@ en:
all_terms_and_conditions:
message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}."
terms_and_conditions: "Terms and Conditions"
agree: By clicking 'Complete order' you agree to your order being processed.
submit: Complete order
cancel: Back to Payment method
errors:

View File

@@ -455,9 +455,8 @@ describe "As a consumer, I want to checkout my order", js: true do
shared_examples "displays the shipping fee" do |checkout_page|
it "on the #{checkout_page} page" do
within "#line-items" do
expect(page).to have_content("Shipping #{with_currency(4.56)}")
end
expect(page).to have_content("Shipping #{with_currency(4.56)}")
if checkout_page.eql?("order confirmation")
expect(page).to have_content "Your order has been processed successfully"
end
@@ -588,9 +587,8 @@ describe "As a consumer, I want to checkout my order", js: true do
shared_examples "displays the transaction fee" do |checkout_page|
it "on the #{checkout_page} page" do
within "#line-items" do
expect(page).to have_content("Transaction fee #{with_currency(1.23)}")
end
expect(page).to have_content("Transaction fee #{with_currency(1.23)}")
if checkout_page.eql?("order confirmation")
expect(page).to have_content "Your order has been processed successfully"
end
@@ -760,10 +758,10 @@ describe "As a consumer, I want to checkout my order", js: true do
end
describe "navigation available" do
it "redirect to Payment method step by clicking on 'Back to payment method' button" do
it "redirect to Payment method step by clicking on 'Payment method' link" do
visit checkout_step_path(:summary)
click_on "Back to Payment method"
click_link "Payment method"
expect(page).to have_content "You can review and confirm your order in the next step which includes the final costs."
end

View File

@@ -216,8 +216,7 @@ describe "As a consumer, I want to see adjustment breakdown" do
expect(page).to have_selector('#order_total', text: with_currency(10.00))
# customer goes back from Summary to Details step, to change Delivery
click_on "Back to Payment method"
click_on "Back to Your details"
click_on "Your details"
end
it "should re-calculate the tax accordingly" do