Skip to content

Commit

Permalink
Upgrade Checkout and Order dropins to latest versions (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
OscarMerino authored Dec 12, 2024
1 parent b10b78a commit b1ef113
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 139 deletions.
231 changes: 111 additions & 120 deletions blocks/commerce-checkout/commerce-checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,6 @@ export default async function decorate(block) {
const SHIPPING_ADDRESS_DATA_KEY = `${SHIPPING_FORM_NAME}_addressData`;
const BILLING_ADDRESS_DATA_KEY = `${BILLING_FORM_NAME}_addressData`;

// Check cart cache
const cart = cartApi.getCartDataFromCache();

// Define the Layout for the Checkout
const checkoutFragment = document.createRange().createContextualFragment(`
<div class="checkout__wrapper">
Expand Down Expand Up @@ -191,96 +188,56 @@ export default async function decorate(block) {
block.appendChild(checkoutFragment);

// Global state
let initialized = false;

// Container and component references
let loader;
let modal;
let emptyCart;
let shippingFormSkeleton;
let billingFormSkeleton;
let shippingFormRef = { current: null };
let billingFormRef = { current: null };
let shippingForm;
let billingForm;
let shippingAddresses;
let billingAddresses;
let placeOrder;
let initialzed = false;

// Dynamic containers and components
const showModal = async (content) => {
modal = await createModal([content]);
modal.showModal();
};

const removeModal = () => {
if (!modal) return;
modal.removeModal();
modal = null;
};

const displayEmptyCart = async () => {
if (emptyCart) return;

emptyCart = await CartProvider.render(EmptyCart, {
routeCTA: () => '/',
})($emptyCart);

$content.classList.add('checkout__content--empty');
};

const removeEmptyCart = () => {
if (!emptyCart) return;

emptyCart.remove();
emptyCart = null;
$emptyCart.innerHTML = '';

$content.classList.remove('checkout__content--empty');
};

const displayOverlaySpinner = async () => {
if (loader) return;

loader = await UI.render(ProgressSpinner, {
className: '.checkout__overlay-spinner',
})($loader);
};

const removeOverlaySpinner = () => {
if (!loader) return;

loader.remove();
loader = null;
$loader.innerHTML = '';
};

const initializeCheckout = async () => {
if (initialzed) return;

await CheckoutProvider.render(MergedCartBanner)($mergedCartBanner);

await UI.render(Header, {
title: 'Checkout',
size: 'large',
divider: true,
})($heading);

await CheckoutProvider.render(ServerError, {
// Render the initial containers
const [
_mergedCartBanner,
_header,
_serverError,
_outOfStock,
_loginForm,
shippingFormSkeleton,
_billToShipping,
_shippingMethods,
_paymentMethods,
billingFormSkeleton,
_orderSummary,
_cartSummary,
placeOrder,
] = await Promise.all([
CheckoutProvider.render(MergedCartBanner)($mergedCartBanner),

UI.render(Header, { title: 'Checkout', size: 'large', divider: true })($heading),

CheckoutProvider.render(ServerError, {
onRetry: () => {
$content.classList.remove('checkout__content--error');
},
onServerError: () => {
$content.classList.add('checkout__content--error');
},
})($serverError);
})($serverError),

await CheckoutProvider.render(OutOfStock, {
CheckoutProvider.render(OutOfStock, {
routeCart: () => '/cart',
onCartProductsUpdate: (items) => {
cartApi.updateProductsFromCart(items).catch(console.error);
},
})($outOfStock);
})($outOfStock),

await CheckoutProvider.render(LoginForm, {
CheckoutProvider.render(LoginForm, {
name: LOGIN_FORM_NAME,
onSignInClick: async (initialEmailValue) => {
const signInForm = document.createElement('div');
Expand All @@ -302,14 +259,14 @@ export default async function decorate(block) {
onSignOutClick: () => {
authApi.revokeCustomerToken();
},
})($login);
})($login),

shippingFormSkeleton = await AccountProvider.render(AddressForm, {
AccountProvider.render(AddressForm, {
isOpen: true,
showFormLoader: true,
})($shippingForm);
})($shippingForm),

await CheckoutProvider.render(BillToShippingAddress, {
CheckoutProvider.render(BillToShippingAddress, {
hideOnVirtualCart: true,
onChange: (checked) => {
$billingForm.style.display = checked ? 'none' : 'block';
Expand All @@ -323,23 +280,23 @@ export default async function decorate(block) {
})({ data: formData, isDataValid });
}
},
})($billToShipping);
})($billToShipping),

await CheckoutProvider.render(ShippingMethods, {
CheckoutProvider.render(ShippingMethods, {
hideOnVirtualCart: true,
onCheckoutDataUpdate: () => {
cartApi.refreshCart().catch(console.error);
},
})($delivery);
})($delivery),

await CheckoutProvider.render(PaymentMethods)($paymentMethods);
CheckoutProvider.render(PaymentMethods)($paymentMethods),

billingFormSkeleton = await AccountProvider.render(AddressForm, {
AccountProvider.render(AddressForm, {
isOpen: true,
showFormLoader: true,
})($billingForm);
})($billingForm),

await CartProvider.render(OrderSummary, {
CartProvider.render(OrderSummary, {
slots: {
EstimateShipping: (esCtx) => {
const estimateShippingForm = document.createElement('div');
Expand All @@ -354,9 +311,9 @@ export default async function decorate(block) {
ctx.appendChild(coupons);
},
},
})($orderSummary);
})($orderSummary),

await CartProvider.render(CartSummaryList, {
CartProvider.render(CartSummaryList, {
variant: 'secondary',
slots: {
Heading: (headingCtx) => {
Expand Down Expand Up @@ -392,9 +349,9 @@ export default async function decorate(block) {
});
},
},
})($cartSummary);
})($cartSummary),

placeOrder = await CheckoutProvider.render(PlaceOrder, {
CheckoutProvider.render(PlaceOrder, {
handleValidation: () => {
let success = true;
const { forms } = document;
Expand Down Expand Up @@ -433,15 +390,67 @@ export default async function decorate(block) {
handlePlaceOrder: async ({ cartId }) => {
await displayOverlaySpinner();

orderApi.placeOrder(cartId)
.catch(console.error)
.finally(() => {
removeOverlaySpinner();
});
await orderApi.placeOrder(cartId).finally(removeOverlaySpinner);
},
})($placeOrder);
})($placeOrder),
]);

// Dynamic containers and components
const showModal = async (content) => {
modal = await createModal([content]);
modal.showModal();
};

const removeModal = () => {
if (!modal) return;
modal.removeModal();
modal = null;
};

const displayEmptyCart = async () => {
if (emptyCart) return;

initialzed = true;
emptyCart = await CartProvider.render(EmptyCart, {
routeCTA: () => '/',
})($emptyCart);

$content.classList.add('checkout__content--empty');
};

const removeEmptyCart = () => {
if (!emptyCart) return;

emptyCart.remove();
emptyCart = null;
$emptyCart.innerHTML = '';

$content.classList.remove('checkout__content--empty');
};

const displayOverlaySpinner = async () => {
if (loader) return;

loader = await UI.render(ProgressSpinner, {
className: '.checkout__overlay-spinner',
})($loader);
};

const removeOverlaySpinner = () => {
if (!loader) return;

loader.remove();
loader = null;
$loader.innerHTML = '';
};

const initializeCheckout = async (data) => {
if (initialized) return;
removeEmptyCart();
if (data.isGuest) await displayGuestAddressForms(data);
else {
removeOverlaySpinner();
await displayCustomerAddressForms(data);
}
};

const displayGuestAddressForms = async (data) => {
Expand Down Expand Up @@ -780,40 +789,21 @@ export default async function decorate(block) {
})($orderConfirmationFooterContinueBtn);
};

// Display the inital view based on the cart cache
if (isCartEmpty(cart)) await displayEmptyCart();
else await initializeCheckout();
// Define the event handlers
const handleCartInitialized = async (data) => {
if (isCartEmpty(data)) await displayEmptyCart();
};

// Event handlers
const handleCheckoutInitialized = async (data) => {
if (isCheckoutEmpty(data)) {
await displayEmptyCart();
return;
}

await initializeCheckout();

if (data.isGuest) {
await displayGuestAddressForms(data);
} else {
await displayCustomerAddressForms(data);
}
if (!data || isCheckoutEmpty(data)) return;
initializeCheckout(data);
};

const handleCheckoutUpdated = async (data) => {
if (isCheckoutEmpty(data)) {
await displayEmptyCart();
return;
}

removeEmptyCart();
await initializeCheckout();

if (data.isGuest) {
await displayGuestAddressForms(data);
} else {
removeOverlaySpinner();
await displayCustomerAddressForms(data);
} else if (!initialized) {
await initializeCheckout(data);
}
};

Expand Down Expand Up @@ -844,6 +834,7 @@ export default async function decorate(block) {
};

events.on('authenticated', handleAuthenticated);
events.on('cart/initialized', handleCartInitialized, { eager: true });
events.on('checkout/initialized', handleCheckoutInitialized, { eager: true });
events.on('checkout/updated', handleCheckoutUpdated);
events.on('order/placed', handleOrderPlaced);
Expand Down
17 changes: 9 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"@dropins/storefront-account": "1.0.0-beta5",
"@dropins/storefront-auth": "1.0.0-beta4",
"@dropins/storefront-cart": "1.0.0-beta2",
"@dropins/storefront-checkout": "1.0.0-beta3",
"@dropins/storefront-order": "1.0.0-beta7",
"@dropins/storefront-checkout": "1.0.0-beta4",
"@dropins/storefront-order": "1.0.0-beta8",
"@dropins/storefront-pdp": "1.0.0-beta3",
"@dropins/tools": "^0.37.0"
}
Expand Down
Loading

0 comments on commit b1ef113

Please sign in to comment.