-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
✨ Marketplace
: Collect Shopper
s Delivery Address before Checkout
#1173
Conversation
Marketplace
: Collect Shopper
s Delivery Address before checkoutMarketplace
: Collect Shopper
s Delivery Address before Checkout
1f9dc06
to
d764872
Compare
</tbody> | ||
<%= render "marketplace/carts/footer", cart: cart %> | ||
</table> | ||
<div id="<%= dom_id(cart) %>"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the indentation change, but I needed to put in an id for the whole shebang so we could replace it all at once :X.
@@ -16,9 +16,6 @@ def create_stripe_session(success_url:, cancel_url:) | |||
mode: "payment", | |||
success_url: success_url, | |||
cancel_url: cancel_url, | |||
shipping_address_collection: { | |||
allowed_countries: ["US"], | |||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to get it from Stripe anymore, since we get it before hand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume: "get it before hand." from the user via this code change that allows the user to input their delivery address in a field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
@@ -1,10 +1,12 @@ | |||
<span id="cart-total-<%= cart.id%>" class="w-full flex flex-col"> | |||
<span class="text-right"> | |||
<span id="cart-total-<%= cart.id%>" class="w-full flex flex-col sm:text-right"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were setting the text-right in every span, which seemed excessive.
The |
</tbody> | ||
<%= render "marketplace/carts/footer", cart: cart %> | ||
</table> | ||
<div id="<%= dom_id(cart) %>"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is dom_id
? what does dom stand for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind. found it in https://apidock.com/rails/ActionView/RecordIdentifier/dom_id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, it's part of the Rails Model/View/Controller coupling; where a unique id
attribute is generated from the model element. It's pretty useful in turbo
land!
<%= button_to("Checkout", cart.location(child: :checkout), data: { turbo: false }) %> | ||
<%- if cart.delivery_address.present? %> | ||
<%= button_to("Checkout", cart.location(child: :checkout), data: { turbo: false }) %> | ||
<%- end %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems to make the checkout button hidden if the user never inputted a cart.delivery_address
. Customers might worry when they don't see the checkout button.
Why not just have the Checkout
disabled if cart.delivery_address
does not exist or is empty string? Or always keep Checkout
enabled, but if they submit the form without the cart.delivery_address
, do not let the form submit and inform them that cart.delivery_address
is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disabled
is better than hidden for sure! I considered making it so if it wasn't set, the CheckoutsController#show
action gave them an affordance for adding the Cart#delivery_address
but I decided against it because it was more code.
I also considered putting the entire cart except for the delivery_address
behind a if/else
block; but that seemed excessive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KellyAH - Do you have a preference between:
- Disabling the
checkout
button unless thedelivery_address
is set, or - Hiding the
cart
until it has adelivery_address
Part of me thinks option 2 is actually worth doing; since it serves as a forcing function and reduces the amount of elements on the page significantly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't 2️⃣ hiding the cart
, freak the customer out since they can't see their cart items. thus they don't know what is in their cart/what happened to their cart.
IMHO 1️⃣ makes it clear that some other required action is needed to be allowed to proceed to the checkout flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can presume a lot about what would or would not freak a customer out, but I don't like to design out of an expectation of fear or anxiety.
It's not terribly unusual for clicking a link to navigate to a different page; so a customer freaking out because when they clicked a link they went somewhere else would surprise me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My hesitation on 2️⃣ is that I just couldn't visualize how it would look in the UI/UX.
If the flow looks fine with the 2️⃣ change and is something you as a customer would be comfy with. I say do 2️⃣ 👍 😄
As we say at work: "Do whatever is easiest/simplest. Because we can always iterate/refactor later"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is 2️⃣'s flow! I think it's pretty decent (but it needs better text! lol)
split-setting-address-from-cart.mp4
@@ -26,7 +26,11 @@ def product_total | |||
end | |||
end | |||
|
|||
delegate :delivery_fee, to: :marketplace | |||
def delivery_fee | |||
return marketplace.delivery_fee if delivery_address.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this logic is covering the fact that the cart.delivery_fee
cannot be calculated without a delivery_address
so it sets delivery_fee
to zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly.
So if I were to make it that smart, I would likely need to promote the But that would have wound up adding a few hundred lines of code; and I didn't want to do that just yet. |
|
||
describe "#update" do | ||
it "changes the delivery address" do | ||
cart = create(:marketplace_cart, marketplace: marketplace, shopper: shopper) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can't the cart
be a let
outside the it
block? Is it because the cart
instance must be created fresh for every it
block? And making cart
a let
would make it a shared object accessed between it
blocks and that would make tests too coupled or possibly cause tests to be flaky if they use/modify the same cart
object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, it's because I didn't have multiple it
statements; but I could pull this into a let
/before
/subject
structure if ya want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave it. it can be pulled out if more it
statements are ever added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wound up finding a bug during my testing, which made me want to write a second test case! So let
it is!
context "when the #delivery_address is present" do | ||
let(:cart) { create(:marketplace_cart, delivery_address: "123", marketplace: marketplace) } | ||
|
||
it { is_expected.to eql(product_a.price + product_b.price + product_b.price + marketplace.delivery_fee) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is product_b.price
listed twice? Is that a typo or is the test increasing product_b
quantity in the cart just by adding a 2nd product_b.price
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, the cart_product
that references product_b
has a quantity of 2
; I could do product_b.price * 2
if that is more clear?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO and nitpick: product_b.price * 2
looks more clear and intentional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
redirect_to cart.room.location | ||
end | ||
format.turbo_stream do | ||
render turbo_stream: [turbo_stream.replace(dom_id(cart), cart)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this logic using turbo stream to AJAX-like update/rerender only the cart item elements on the webpage instead of rerendering the whole page?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep!
- #1136 While collecting the address via Stripe was reasonable at the time, if we want to support dynamic pricing, we'll need the address ahead of time. This will also (theoretically) allow us to let people know when they are outside of the `Distributor` delivery area.
Co-authored-by: KellyAH <[email protected]>
383d57f
to
bc7f76b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
waiting for https://github.com/zinc-collective/convene/pull/1173/files#r1124122135 to be resolved, then I will approve this PR. The rest of the code looks great 💎 😄
It's probably worth pushing some of these expectations down to the `cart_policy_spec` level, but the bug manifested at the controller tier so I wanted to catch it there.
Marketplace
:DeliveryArea
#1136While collecting the address via Stripe was reasonable at the time, if we want to support dynamic pricing, we'll need the address ahead of time.
This will also (theoretically) allow us to let people know when they are outside of the
Distributor
delivery area.After!
split-setting-address-from-cart.mp4
Before
before-address-collected.mp4