From 577c91aca5500d67ffe34e51ada03bbf333cf29c Mon Sep 17 00:00:00 2001 From: Will Marshall Date: Mon, 7 Apr 2014 16:15:19 +1000 Subject: [PATCH] Starting on the improved accordion checkout --- .../controllers/checkout_controller.js.coffee | 3 + .../stylesheets/darkswarm/forms.css.sass | 20 ++- app/views/shop/checkout/_billing.html.haml | 34 +++++ app/views/shop/checkout/_details.html.haml | 21 +++ app/views/shop/checkout/_form.html.haml | 136 +----------------- app/views/shop/checkout/_order.rabl | 11 +- app/views/shop/checkout/_payment.html.haml | 19 +++ app/views/shop/checkout/_shipping.html.haml | 81 +++++++++++ app/views/shop/checkout/edit.html.haml | 18 +-- .../consumer/shopping/checkout_auth_spec.rb | 69 +++------ .../consumer/shopping/checkout_spec.rb | 5 + spec/support/request/shop_workflow.rb | 4 + 12 files changed, 229 insertions(+), 192 deletions(-) create mode 100644 app/views/shop/checkout/_billing.html.haml create mode 100644 app/views/shop/checkout/_details.html.haml create mode 100644 app/views/shop/checkout/_payment.html.haml create mode 100644 app/views/shop/checkout/_shipping.html.haml diff --git a/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee index 1d0604d76c..528e809b6f 100644 --- a/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/checkout_controller.js.coffee @@ -18,6 +18,9 @@ Darkswarm.controller "CheckoutCtrl", ($scope, $rootScope, order) -> $scope.shippingMethod = -> $scope.order.shipping_methods[$scope.order.shipping_method_id] + $scope.paymentMethod = -> + $scope.order.payment_methods[$scope.order.payment_method_id] + $scope.shippingMethodChanged = -> $scope.require_ship_address = $scope.shippingMethod().require_ship_address if $scope.shippingMethod() diff --git a/app/assets/stylesheets/darkswarm/forms.css.sass b/app/assets/stylesheets/darkswarm/forms.css.sass index bada1fb68d..e519b2818f 100644 --- a/app/assets/stylesheets/darkswarm/forms.css.sass +++ b/app/assets/stylesheets/darkswarm/forms.css.sass @@ -1,6 +1,6 @@ @import variables -form +.darkswarm fieldset padding: 0px border: none @@ -12,5 +12,23 @@ form display: block width: 100% margin-bottom: 1em + color: #999999 + text-transform: uppercase + dd a + border: 1px solid $dark-grey + border-left: 0px + border-right: 0px + padding: 16px 24px + display: block + width: 100% + margin-bottom: 1em + color: #999999 text-transform: uppercase color: #999999 + font-weight: bold + text-transform: uppercase + background: transparent + .text-right + font-weight: normal + text-transform: none + diff --git a/app/views/shop/checkout/_billing.html.haml b/app/views/shop/checkout/_billing.html.haml new file mode 100644 index 0000000000..ccf1d49091 --- /dev/null +++ b/app/views/shop/checkout/_billing.html.haml @@ -0,0 +1,34 @@ +%fieldset#billing + %accordion-group + %accordion-heading + .row + .large-6.columns + Billing + .large-6.columns.text-right + {{ order.bill_address.address1 }} + {{ order.bill_address.city }} + = f.fields_for :bill_address, @order.bill_address do |ba| + .row + .large-12.columns + = ba.text_field :address1, + "ng-model" => "order.bill_address.address1" + .row + .large-12.columns + = ba.text_field :address2, + "ng-model" => "order.bill_address.address2" + .row + .large-6.columns + + = ba.text_field :city, + "ng-model" => "order.bill_address.city" + + .large-6.columns + = ba.select :state_id, @order.billing_address.country.states.map{|c|[c.name, c.id]}, + "ng-model" => "order.bill_address.state_id" + .row + .large-6.columns + = ba.text_field :zipcode, label: "Postcode", + "ng-model" => "order.bill_address.zipcode" + .large-6.columns.right + = ba.select :country_id, available_countries.map{|c|[c.name, c.id]}, + {include_blank: false}, "ng-model" => "order.bill_address.country_id" diff --git a/app/views/shop/checkout/_details.html.haml b/app/views/shop/checkout/_details.html.haml new file mode 100644 index 0000000000..241a65c4d6 --- /dev/null +++ b/app/views/shop/checkout/_details.html.haml @@ -0,0 +1,21 @@ +%fieldset#details + %accordion-group + %accordion-heading + .row + .large-6.columns + Customer Details + .large-6.columns.text-right + {{ order.bill_address.firstname }} + {{ order.bill_address.lastname }} + .row + .large-6.columns + = f.text_field :email + = f.fields_for :bill_address, @order.bill_address do |ba| + .large-6.columns + = ba.text_field :phone, "ng-model" => "order.bill_address.phone" + = f.fields_for :bill_address, @order.bill_address do |ba| + .row + .large-6.columns + = ba.text_field :firstname, "ng-model" => "order.bill_address.firstname" + .large-6.columns + = ba.text_field :lastname, "ng-model" => "order.bill_address.lastname" diff --git a/app/views/shop/checkout/_form.html.haml b/app/views/shop/checkout/_form.html.haml index 8ac9f67c90..759baabd64 100644 --- a/app/views/shop/checkout/_form.html.haml +++ b/app/views/shop/checkout/_form.html.haml @@ -9,135 +9,7 @@ -#{{ order | json }} .large-12.columns - %fieldset#details - %legend Customer Details - .row - .large-6.columns - = f.text_field :email - = f.fields_for :bill_address, @order.bill_address do |ba| - .large-6.columns - = ba.text_field :phone, "ng-model" => "order.bill_address.phone" - = f.fields_for :bill_address, @order.bill_address do |ba| - .row - .large-6.columns - = ba.text_field :firstname, "ng-model" => "order.bill_address.firstname" - .large-6.columns - = ba.text_field :lastname, "ng-model" => "order.bill_address.lastname" - - %fieldset#billing - %legend Billing Address - = f.fields_for :bill_address, @order.bill_address do |ba| - .row - .large-12.columns - = ba.text_field :address1, - "ng-model" => "order.bill_address.address1" - .row - .large-12.columns - = ba.text_field :address2, - "ng-model" => "order.bill_address.address2" - .row - .large-6.columns - - = ba.text_field :city, - "ng-model" => "order.bill_address.city" - - .large-6.columns - = ba.select :state_id, @order.billing_address.country.states.map{|c|[c.name, c.id]}, - "ng-model" => "order.bill_address.state_id" - .row - .large-6.columns - = ba.text_field :zipcode, label: "Postcode", - "ng-model" => "order.bill_address.zipcode" - .large-6.columns.right - = ba.select :country_id, available_countries.map{|c|[c.name, c.id]}, - {include_blank: false}, "ng-model" => "order.bill_address.country_id" - - %fieldset#shipping - %legend Shipping - - for ship_method, i in current_distributor.shipping_methods.uniq - .row - .large-12.columns - -#= f.radio_button :shipping_method_id, ship_method.id, - -#text: ship_method.name, - -#"ng-change" => "shippingMethodChanged()", - -#"ng-model" => "order.shipping_method_id" - %label - = radio_button_tag "order[shipping_method_id]", ship_method.id, false, - "ng-change" => "shippingMethodChanged()", - "ng-model" => "order.shipping_method_id" - = ship_method.name - - #distributor_address.panel{"ng-show" => "!require_ship_address"} - = @order.distributor.distributor_info.andand.html_safe - = @order.order_cycle.pickup_time_for(@order.distributor) - = @order.order_cycle.pickup_instructions_for(@order.distributor) - - = f.fields_for :ship_address, @order.ship_address do |sa| - - #ship_address{"ng-show" => "require_ship_address"} - %label - = hidden_field_tag "order[ship_address_same_as_billing]", "false" - = check_box_tag "order[ship_address_same_as_billing]", true, @order.ship_address_same_as_billing, - "ng-model" => "order.ship_address_same_as_billing" - Shipping address same as billing address? - - %div.visible{"ng-show" => "!order.ship_address_same_as_billing"} - .row - .large-12.columns - = sa.text_field :address1 - .row - - .large-12.columns - = sa.text_field :address2 - - .row - .large-6.columns - = sa.text_field :city - .large-6.columns - = sa.select :state_id, @order.shipping_address.country.states.map{|c|[c.name, c.id]} - .row - .large-6.columns - = sa.text_field :zipcode, label: "Postcode" - .large-6.columns.right - = sa.select :country_id, available_countries.map{|c|[c.name, c.id]}, - {include_blank: false} - .row - .large-6.columns - = sa.text_field :firstname - .large-6.columns - = sa.text_field :lastname - .row - .large-6.columns - = sa.text_field :phone - - #ship_address_hidden{"ng-show" => "order.ship_address_same_as_billing"} - = sa.hidden_field :address1, "ng-value" => "order.bill_address.address1", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :address2, "ng-value" => "order.bill_address.address2", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :city, "ng-value" => "order.bill_address.city", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :country_id, "ng-value" => "order.bill_address.country_id", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :zipcode, "ng-value" => "order.bill_address.zipcode", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :firstname, "ng-value" => "order.bill_address.firstname", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :lastname, "ng-value" => "order.bill_address.lastname", - "ng-disabled" => "!order.ship_address_same_as_billing" - = sa.hidden_field :phone, "ng-value" => "order.bill_address.phone", - "ng-disabled" => "!order.ship_address_same_as_billing" - - %fieldset#payment - %legend Payment Details - - current_order.available_payment_methods.each do |method| - .row - .large-12.columns - %label - = radio_button_tag "order[payments_attributes][][payment_method_id]", method.id, false, - "ng-model" => "order.payment_method_id" - = method.name - .row{"ng-show" => "order.payment_method_id == #{method.id}"} - .large-12.columns - = render partial: "spree/checkout/payment/#{method.method_type}", :locals => { :payment_method => method } - + = render partial: "shop/checkout/details", locals: {f: f} + = render partial: "shop/checkout/billing", locals: {f: f} + = render partial: "shop/checkout/shipping", locals: {f: f} + = render partial: "shop/checkout/payment", locals: {f: f} diff --git a/app/views/shop/checkout/_order.rabl b/app/views/shop/checkout/_order.rabl index 09451830fb..4bba881fec 100644 --- a/app/views/shop/checkout/_order.rabl +++ b/app/views/shop/checkout/_order.rabl @@ -22,7 +22,16 @@ node :shipping_methods do Hash[current_order.distributor.shipping_methods.collect { |method| [method.id, { require_ship_address: method.require_ship_address, - price: method.compute_amount(current_order).to_f + price: method.compute_amount(current_order).to_f, + name: method.name + }] + }] +end + +node :payment_methods do + Hash[current_order.available_payment_methods.collect { + |method| [method.id, { + name: method.name }] }] end diff --git a/app/views/shop/checkout/_payment.html.haml b/app/views/shop/checkout/_payment.html.haml new file mode 100644 index 0000000000..3a68e74321 --- /dev/null +++ b/app/views/shop/checkout/_payment.html.haml @@ -0,0 +1,19 @@ +%fieldset#payment + %accordion-group + %accordion-heading + .row + .large-6.columns + Payment Details + .large-6.columns.text-right + {{ paymentMethod().name }} + - current_order.available_payment_methods.each do |method| + .row + .large-12.columns + %label + = radio_button_tag "order[payments_attributes][][payment_method_id]", method.id, false, + "ng-model" => "order.payment_method_id" + = method.name + .row{"ng-show" => "order.payment_method_id == #{method.id}"} + .large-12.columns + = render partial: "spree/checkout/payment/#{method.method_type}", :locals => { :payment_method => method } + diff --git a/app/views/shop/checkout/_shipping.html.haml b/app/views/shop/checkout/_shipping.html.haml new file mode 100644 index 0000000000..2f57bb9cb5 --- /dev/null +++ b/app/views/shop/checkout/_shipping.html.haml @@ -0,0 +1,81 @@ +%fieldset#shipping + %accordion-group + %accordion-heading + .row + .large-6.columns + Shipping + .large-6.columns.text-right + {{ shippingMethod().name }} + - for ship_method, i in current_distributor.shipping_methods.uniq + .row + .large-12.columns + -#= f.radio_button :shipping_method_id, ship_method.id, + -#text: ship_method.name, + -#"ng-change" => "shippingMethodChanged()", + -#"ng-model" => "order.shipping_method_id" + %label + = radio_button_tag "order[shipping_method_id]", ship_method.id, false, + "ng-change" => "shippingMethodChanged()", + "ng-model" => "order.shipping_method_id" + = ship_method.name + + #distributor_address.panel{"ng-show" => "!require_ship_address"} + = @order.distributor.distributor_info.andand.html_safe + = @order.order_cycle.pickup_time_for(@order.distributor) + = @order.order_cycle.pickup_instructions_for(@order.distributor) + + = f.fields_for :ship_address, @order.ship_address do |sa| + + #ship_address{"ng-show" => "require_ship_address"} + %label + = hidden_field_tag "order[ship_address_same_as_billing]", "false" + = check_box_tag "order[ship_address_same_as_billing]", true, @order.ship_address_same_as_billing, + "ng-model" => "order.ship_address_same_as_billing" + Shipping address same as billing address? + + %div.visible{"ng-show" => "!order.ship_address_same_as_billing"} + .row + .large-12.columns + = sa.text_field :address1 + .row + + .large-12.columns + = sa.text_field :address2 + + .row + .large-6.columns + = sa.text_field :city + .large-6.columns + = sa.select :state_id, @order.shipping_address.country.states.map{|c|[c.name, c.id]} + .row + .large-6.columns + = sa.text_field :zipcode, label: "Postcode" + .large-6.columns.right + = sa.select :country_id, available_countries.map{|c|[c.name, c.id]}, + {include_blank: false} + .row + .large-6.columns + = sa.text_field :firstname + .large-6.columns + = sa.text_field :lastname + .row + .large-6.columns + = sa.text_field :phone + + #ship_address_hidden{"ng-show" => "order.ship_address_same_as_billing"} + = sa.hidden_field :address1, "ng-value" => "order.bill_address.address1", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :address2, "ng-value" => "order.bill_address.address2", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :city, "ng-value" => "order.bill_address.city", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :country_id, "ng-value" => "order.bill_address.country_id", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :zipcode, "ng-value" => "order.bill_address.zipcode", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :firstname, "ng-value" => "order.bill_address.firstname", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :lastname, "ng-value" => "order.bill_address.lastname", + "ng-disabled" => "!order.ship_address_same_as_billing" + = sa.hidden_field :phone, "ng-value" => "order.bill_address.phone", + "ng-disabled" => "!order.ship_address_same_as_billing" diff --git a/app/views/shop/checkout/edit.html.haml b/app/views/shop/checkout/edit.html.haml index 98cead9b9f..bca55e2a54 100644 --- a/app/views/shop/checkout/edit.html.haml +++ b/app/views/shop/checkout/edit.html.haml @@ -7,16 +7,18 @@ = render partial: "shop/details" %checkout - .row + %accordion.row{"close-others" => "false"} .large-9.columns - unless spree_current_user - .row - %section#checkout_login - .large-6.columns - = render partial: "shop/checkout/login" - %section#checkout_signup - .large-6.columns - = render partial: "shop/checkout/signup" + %fieldset + %accordion-group{heading: "User"} + .row + %section#checkout_login + .large-6.columns + = render partial: "shop/checkout/login" + %section#checkout_signup + .large-6.columns + = render partial: "shop/checkout/signup" .row = render partial: "shop/checkout/form" diff --git a/spec/features/consumer/shopping/checkout_auth_spec.rb b/spec/features/consumer/shopping/checkout_auth_spec.rb index 6ad1ab89d4..f7c48664f8 100644 --- a/spec/features/consumer/shopping/checkout_auth_spec.rb +++ b/spec/features/consumer/shopping/checkout_auth_spec.rb @@ -23,61 +23,30 @@ feature "As a consumer I want to check out my cart", js: true do add_product_to_cart end - it "renders the login form if user is logged out" do - visit "/shop/checkout" - within "section[role='main']" do - page.should have_content "I HAVE AN OFN ACCOUNT" + + context "logged in" do + before do + login_to_consumer_section + visit "/shop/checkout" + end + it "does not not render the login form" do + within "section[role='main']" do + page.should_not have_content "USER" + end end end - it "does not not render the login form if user is logged in" do - login_to_consumer_section - visit "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "I HAVE AN OFN ACCOUNT" - end - end - - it "renders the signup link if user is logged out" do - visit "/shop/checkout" - within "section[role='main']" do - page.should have_content "NEW TO OFN" - end - end - - it "does not not render the signup form if user is logged in" do - login_to_consumer_section - visit "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "NEW TO OFN" - end - end - - it "redirects to the checkout page when logging in from the checkout page" do - visit "/shop/checkout" - within "#checkout_login" do - fill_in "spree_user[email]", with: user.email - fill_in "spree_user[password]", with: user.password - click_button "Login" + context "logged out" do + before do + visit "/shop/checkout" + save_and_open_page + toggle_accordion "User" end - current_path.should == "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "I have an OFN Account" - end - end - - it "redirects to the checkout page when signing up from the checkout page" do - visit "/shop/checkout" - within "#checkout_signup" do - fill_in "spree_user[email]", with: "test@gmail.com" - fill_in "spree_user[password]", with: "password" - fill_in "spree_user[password_confirmation]", with: "password" - click_button "Sign Up" - end - current_path.should == "/shop/checkout" - within "section[role='main']" do - page.should_not have_content "Sign Up" + it "renders the login form if user is logged out" do + within "section[role='main']" do + page.should have_content "USER" + end end end end diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index 7cf28675e1..47a6e97962 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -36,6 +36,11 @@ feature "As a consumer I want to check out my cart", js: true do distributor.shipping_methods << sm1 distributor.shipping_methods << sm2 visit "/shop/checkout" + click_link "USER" + click_link "CUSTOMER DETAILS" + click_link "BILLING" + click_link "SHIPPING" + click_link "PAYMENT DETAILS" end it "shows all shipping methods, but doesn't show ship address when not needed" do page.should have_content "Frogs" diff --git a/spec/support/request/shop_workflow.rb b/spec/support/request/shop_workflow.rb index 414c7a4fa1..3a13754299 100644 --- a/spec/support/request/shop_workflow.rb +++ b/spec/support/request/shop_workflow.rb @@ -16,4 +16,8 @@ module ShopWorkflow def add_product_to_cart create(:line_item, variant: product.master, order: order) end + + def toggle_accordion(name) + find("dd[heading='#{name}'] > a").click + end end