From 73a447bbe4504f251d1545fe26a37041a2414081 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 16:23:41 -0300 Subject: [PATCH 01/53] feat: redesign modal checkout --- includes/class-modal-checkout.php | 120 +++++- src/modal-checkout/checkout.scss | 367 ++++++------------ src/modal-checkout/index.js | 45 +-- src/modal-checkout/modal.scss | 34 +- .../templates/checkout-form.php | 162 ++------ 5 files changed, 282 insertions(+), 446 deletions(-) diff --git a/includes/class-modal-checkout.php b/includes/class-modal-checkout.php index 98de2260b..7acfc4061 100644 --- a/includes/class-modal-checkout.php +++ b/includes/class-modal-checkout.php @@ -51,6 +51,9 @@ public static function init() { add_filter( 'wcs_place_subscription_order_text', [ __CLASS__, 'order_button_text' ], 1 ); add_filter( 'woocommerce_order_button_text', [ __CLASS__, 'order_button_text' ] ); add_filter( 'option_woocommerce_subscriptions_order_button_text', [ __CLASS__, 'order_button_text' ] ); + add_action( 'woocommerce_checkout_before_terms_and_conditions', [ __CLASS__, 'render_before_terms_and_conditions' ] ); + add_action( 'woocommerce_checkout_before_customer_details', [ __CLASS__, 'render_before_customer_details' ] ); + add_filter( 'woocommerce_enable_order_notes_field', [ __CLASS__, 'enable_order_notes_field' ] ); } /** @@ -256,18 +259,29 @@ public static function render_modal_markup() { if ( ! self::$has_modal ) { return; } + /** + * Filters the header title for the modal checkout. + * + * @param string $title The title. + */ + $title = apply_filters( 'newspack_blocks_modal_checkout_title', __( 'Complete your transaction', 'newspack-blocks' ) ); ?> '; - } - wp_footer(); + ?> + + > + + + + + + + + + + + 'src/modal-checkout/templates/checkout-form.php', - 'checkout/form-billing.php' => 'src/modal-checkout/templates/billing-form.php', 'checkout/thankyou.php' => 'src/modal-checkout/templates/thankyou.php', // Replace the login form with the order summary if using the modal checkout. This is // for the case where the reader used an existing email address. @@ -926,5 +951,62 @@ public static function order_button_text( $text ) { } return $text; } + + /** + * Render before checkout terms and conditions. + * + * This will render the order review table between the gateway selection and + * the submit button. + */ + public static function render_before_terms_and_conditions() { + if ( ! self::is_modal_checkout() ) { + return; + } + // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WooCommerce hooks. + ?> + +

+ +
+ +
+ + + + + + + span { - color: inherit; - font-size: clamp( 1.75rem, 1.75rem + ( ( 1vw - 0.48rem ) * 0.962 ), 2.25rem ); - font-weight: bold; - line-height: 1.434; +#newspack_modal_checkout { + padding: 24px; + h3 { + font-size: 16px; + margin: 24px 0 16px; + } + .woocommerce-message, + .woocommerce-error, + .woocommerce-info { + border-radius: 6px; + } + input[type='text'], + input[type='email'], + input[type='tel'], + input[type='number'], + input[type='password'], + input[type='submit'], + select, + textarea { + border-radius: 6px; + padding: 12px 16px; + font-size: 14px; + line-height: 24px; + } + #customer_details { + .woocommerce-billing-fields { + p { + margin: 8px 0 24px; } - .subscription-details { - font-size: 1rem; - font-weight: normal; + label { + font-size: 14px; + line-height: 20px; + font-weight: 600; + margin-bottom: 8px; } } } - #order-details-wrapper.hidden { - display: none; - } - .woocommerce-NoticeGroup { - margin-top: 16px; - } - .woocommerce-checkout-review-order-table { - margin-top: 16px; - th, - td { - font-size: 0.8rem; - } - &.empty { - display: none; - margin: 0; - padding: 0; - } - } - .woocommerce-billing-fields { - margin-bottom: 16px; - } - .checkout-billing-summary { - border-bottom: 1px solid colors.$color__border; - padding-bottom: 32px; - &__grid { - align-items: baseline; - display: flex; - flex-wrap: wrap; - gap: 8px; - justify-content: space-between; - } - p { - font-size: clamp( 0.75rem, 0.75rem + ( ( 1vw - 0.48rem ) * 0.481 ), 1rem ); - margin: 16px 0 0; - } - .edit-billing-link { - color: colors.$color__text-light; - font-size: clamp( 0.75rem, 0.75rem + ( ( 1vw - 0.48rem ) * 0.481 ), 1rem ); - display: inline-block; - text-decoration: underline; - &:focus, - &:hover { - color: inherit; + #payment { + .wc_payment_method { + border: 1px solid #ddd; + border-radius: 6px; + padding: 16px; + margin: 0 0 16px; + font-size: 14px; + line-height: 20px; + > label { + font-weight: 600; + } + &.selected { + background-color: #f5fdff; + border-color: #3366ff; + } + input.input-radio[name='payment_method'] + label::before { + box-shadow: 0 0 0 1px #dddddd; + } + input.input-radio[name='payment_method']:checked + label::before { + background: #3366ff; + box-shadow: 0 0 0 1px #3366ff; + } + .payment_box { + font-size: 14px; + line-height: 20px; + padding: 0; + background: transparent; + margin: 16px 0 0; + } + > label:first-of-type { + margin: 0; } } - } - .woocommerce-account-fields .create-account { - border-bottom: 1px solid colors.$color__border; - padding-bottom: 32px; - - .woocommerce-password-strength, - .woocommerce-password-hint { - color: colors.$color__error; + .woocommerce-SavedPaymentMethods-saveNew { + display: flex; + align-items: center; margin-top: 16px; + input { + margin-right: 8px; + } } - } - - form { - margin: 0; - #wc-stripe-payment-request-button-separator { - margin: 0; - } - .woocommerce-terms-and-conditions-wrapper { - margin: 16px 0; - } - h3 { - font-size: 1.37rem; - margin: 32px 0 0; - } - p { - margin: 16px 0; - } - .select2-container .select2-selection--single { - margin: 0; - } - #payment button#place_order { /* stylelint-disable-line */ - margin-bottom: 0; - } - .checkout-billing button[type='submit'], - button[name='woocommerce_checkout_place_order'], - button.modal-continue { + #place_order { + background-color: var( --newspack-theme-color-primary ); + font-size: 14px; + font-weight: 600; display: block; width: 100%; } } - .form-row-first, - .form-row-last { - width: calc( 50% - 8px ); - } - .form-row-wide + .form-row-first, - .form-row-wide + .form-row-first + .form-row-last, - .form-row-last + .form-row-first { - margin-top: 0; - } - .select2-container--default { - .select2-selection--single { - border-color: colors.$color__border; - border-radius: 0; - height: 44px; - .select2-selection__rendered { - color: inherit; - line-height: 44px; + #order_review { + padding: 16px 24px; + border-radius: 6px; + background: #f6f7f7; + table { + font-size: 14px; // Prevent relative font size + line-height: 24px; + border: 0; + margin: 0; + th, + td { + font-size: 14px; // Prevent relative font size + padding: 4px 0; + border-color: #dddddd; + white-space: nowrap; + vertical-align: top; } - .select2-selection__arrow { - height: 42px; + th { + background-color: inherit; + font-weight: 600; + text-align: left; + } + th:first-child { + width: 100%; + } + tr.cart-subtotal { + th { + font-weight: normal; + } + } + tr.recurring-totals { + th { + padding-top: 24px; + } + } + tfoot tr:last-child { + th, + td { + border-bottom: 0; + } } } } - .wc_payment_method .payment_box { - background: colors.$color__gray-lighter; - border-radius: 3px; - padding: 16px; - p { - margin-top: 0; - } - } - .wc-saved-payment-methods { - padding: 0; - } - .woocommerce-error { - border-radius: 3px; - margin: 0; - } - .woocommerce-notices-wrapper:not( :empty ) { - margin-bottom: 32px; - } .woocommerce-privacy-policy-text { - color: colors.$color__text-light; - p { - font-size: clamp( 0.75rem, 0.75rem + ( ( 1vw - 0.48rem ) * 0.481 ), 1rem ); - margin: 0; - } - } - .woocommerce-thankyou-order-received { - align-items: center; - border-bottom: 1px solid colors.$color__border; - display: flex; - flex-direction: column; - justify-content: center; - margin: 0 0 32px; - padding: 0 0 32px; - &::before { - animation: bounce 250ms ease-in; - animation-delay: 1s; - animation-fill-mode: forwards; - background-color: colors.$color__success; - background-image: url( "data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z' fill='white'/%3E%3C/svg%3E" ); - background-position: 50% 50%; - background-repeat: no-repeat; - background-size: 24px; - border-radius: 50%; - content: ''; - display: block; - height: 40px; - margin-bottom: 16px; - padding: 8px; - transform: scale( 0 ); - width: 40px; - } - + .woocommerce-info { - display: none; // Hide the "Please log in to view this order" message on the thank you page. - } - } - .woocommerce-form-login-toggle { - display: none; // Hide the "Returning customer? Click here to login" message. - } - .woocommerce-order-overview { - color: colors.$color__text-light; - list-style: none; - margin: 16px 0 0; - padding: 0; - } - - .blockOverlay { - align-items: center; - display: flex; - inset: 0; - justify-content: center; - position: fixed !important; - &::after { - animation: spin 1s infinite linear; - border: 2px solid colors.$color__background-body; - border-top-color: colors.$color__text-light; - border-radius: 50%; - content: ''; - display: block; - height: 25px; - width: 25px; - } - } -} - -.newspack-modal-newsletters { - margin-top: 20px; - padding-top: 22px; - border-top: 1px solid colors.$color__border; - &__info { - margin-bottom: 35px; - span { - color: colors.$color__text-light; - } - } - &__list-item { - display: flex; - margin-bottom: 18px; - border: 1px solid colors.$color__border; - border-radius: 6px; - b { - display: block; - margin-bottom: 2px; - } - } - label { - flex: 1; - padding: 12px; - cursor: pointer; - } - input[type='checkbox'] { - padding: 10px; - margin-top: 18px; - margin-right: 19px; - margin-left: 20px; - border-radius: 5px; - } - input[type='submit'], - &__button { - margin-top: 25px; - width: 100%; - padding: 22px !important; - font-size: 1em !important; - } -} - -@keyframes bounce { - 0% { - transform: scale( 0 ); - } - 90% { - transform: scale( 1.4 ); + font-size: 14px; + line-height: 20px; + color: #757575; } - 100% { - transform: scale( 1 ); + /* Hide reCAPTCHA badge */ + .grecaptcha-badge { + visibility: hidden !important; } } diff --git a/src/modal-checkout/index.js b/src/modal-checkout/index.js index 5ffcbae1c..224ec9721 100644 --- a/src/modal-checkout/index.js +++ b/src/modal-checkout/index.js @@ -1,36 +1,23 @@ +/* globals jQuery */ /** * Style dependencies */ import './checkout.scss'; -/** - * Specify a function to execute when the DOM is fully loaded. - * - * @see https://github.com/WordPress/gutenberg/blob/trunk/packages/dom-ready/ - * - * @param {Function} callback A function to execute after the DOM is ready. - * @return {void} - */ -function domReady( callback ) { - if ( typeof document === 'undefined' ) { +( function ( $ ) { + if ( ! $ ) { return; } - if ( - document.readyState === 'complete' || // DOMContentLoaded + Images/Styles/etc loaded, so we call directly. - document.readyState === 'interactive' // DOMContentLoaded fires at this point, so we call directly. - ) { - return void callback(); - } - // DOMContentLoaded has not fired yet, delay callback until then. - document.addEventListener( 'DOMContentLoaded', callback ); -} - -domReady( () => { - const continueButton = document.querySelector( '.modal-continue' ); - if ( continueButton ) { - continueButton.addEventListener( 'click', () => { - const form = document.querySelector( '.checkout' ); - form.submit(); - } ); - } -} ); + const handleMethodSelected = () => { + const selected = $( 'input[name="payment_method"]:checked' ).val(); + $( '.wc_payment_method' ).removeClass( 'selected' ); + $( '.wc_payment_method.payment_method_' + selected ).addClass( 'selected' ); + }; + $( document ).ready( function () { + $( document ).on( 'payment_method_selected', handleMethodSelected ); + $( document ).on( 'updated_checkout', handleMethodSelected ); + $( 'input[name="payment_method"]' ).change( handleMethodSelected ); + handleMethodSelected(); + // setTimeout( handleMethodSelected, 1000 ); + } ); +} )( jQuery ); diff --git a/src/modal-checkout/modal.scss b/src/modal-checkout/modal.scss index 2bc76b43c..fa1b9df34 100644 --- a/src/modal-checkout/modal.scss +++ b/src/modal-checkout/modal.scss @@ -21,22 +21,39 @@ height: 100%; background: rgba( 0, 0, 0, 0.75 ); z-index: 99999; - &__content { + &__container { + border-radius: 6px; + background: colors.$color__background-body; position: absolute; top: 50%; left: 50%; transform: translate( -50%, -50% ); width: calc( 100vw - 32px ); - max-width: 580px; - min-height: 200px; + max-width: 600px; + min-height: 250px; max-height: calc( 100vh - 32px ); - background: colors.$color__background-body; - border-radius: 5px; - > *:not( .newspack-blocks-modal__close ) { + display: flex; + flex-direction: column; + justify-content: space-between; + } + &__header { + padding: 24px; + box-sizing: border-box; + height: 64px; + border-bottom: 1px solid #ddd; + display: flex; + align-items: center; + justify-content: space-between; + h2 { + font-size: 16px; + } + } + &__content { + > * { width: 100%; height: 100%; border: 0; - border-radius: 5px; + border-radius: 6px; } } &__spinner { @@ -62,9 +79,6 @@ } } &__close { - position: absolute; - top: 0; - right: 0; padding: 8px; border: 0; background: transparent; diff --git a/src/modal-checkout/templates/checkout-form.php b/src/modal-checkout/templates/checkout-form.php index f29c535a1..2a648129a 100644 --- a/src/modal-checkout/templates/checkout-form.php +++ b/src/modal-checkout/templates/checkout-form.php @@ -1,166 +1,48 @@ cart; - -$has_filled_billing = \Newspack_Blocks\Modal_Checkout::has_filled_required_fields( 'billing' ); -$edit_billing = ! $has_filled_billing || isset( $_REQUEST['edit_billing'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - -$form_action = $edit_billing ? '#checkout' : wc_get_checkout_url(); -$form_class = 'checkout woocommerce-checkout'; -$form_method = $edit_billing ? 'get' : 'post'; -$form_billing_fields = \Newspack_Blocks\Modal_Checkout::get_prefilled_fields(); - -$after_success_behavior = filter_input( INPUT_GET, 'after_success_behavior', FILTER_SANITIZE_STRING ); -$after_success_url = filter_input( INPUT_GET, 'after_success_url', FILTER_SANITIZE_STRING ); -$after_success_button_label = filter_input( INPUT_GET, 'after_success_button_label', FILTER_SANITIZE_STRING ); - -if ( $edit_billing ) { - $form_class .= ' edit-billing'; +if ( ! defined( 'ABSPATH' ) ) { + exit; } do_action( 'woocommerce_before_checkout_form', $checkout ); // If checkout registration is disabled and not logged in, the user cannot checkout. if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) { - echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'newspack-blocks' ) ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'newspack-blocks' ) ) ); return; } -?> - -get_cart_contents_count() ) : ?> -
- get_cart() as $cart_item_key => $cart_item ) { - $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); - - if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { - ?> -

- - - get_name(), $cart_item, $cart_item_key ) . ' '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo wc_get_formatted_cart_item_data( $cart_item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - ?> - - - get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - ?> - -

- -
- -
- - - - - - - - -
- -

- -
- -
- -
+?> + get_checkout_fields() ) : ?> - - - -
- - -
- -
-
-

- -
-

-
- countries->get_formatted_address( $form_billing_fields ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> -

-
- $value ) : ?> - - countries->get_states( $form_billing_fields['country'] ); ?> - - - - - - - - is_registration_enabled() ) : ?> - - +
+ + +
-
- -
- + From ca7d382a8817c3ec45412fc81021cf0e75c5a7bf Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 16:47:27 -0300 Subject: [PATCH 02/53] fix: saved methods spacing --- src/modal-checkout/checkout.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/modal-checkout/checkout.scss b/src/modal-checkout/checkout.scss index 8900b3661..c37b3e947 100644 --- a/src/modal-checkout/checkout.scss +++ b/src/modal-checkout/checkout.scss @@ -68,6 +68,13 @@ margin: 0; } } + .wc-saved-payment-methods { + margin: 0 0 16px; + padding: 0 0 0 8px; + li input[type='radio'] { + margin-right: 8px; + } + } .woocommerce-SavedPaymentMethods-saveNew { display: flex; align-items: center; From 07f3cddc9c4821aa834c59a9aa30da8c46c56bf5 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 17:59:33 -0300 Subject: [PATCH 03/53] fix: style updates and start custom coupon form --- includes/class-modal-checkout.php | 1 + src/modal-checkout/checkout.scss | 26 +++++++++-- src/modal-checkout/index.js | 5 ++- src/modal-checkout/modal.scss | 15 ++++--- src/modal-checkout/templates/billing-form.php | 43 ------------------- .../templates/checkout-form.php | 4 +- src/modal-checkout/templates/form-coupon.php | 23 ++++++++++ 7 files changed, 62 insertions(+), 55 deletions(-) delete mode 100644 src/modal-checkout/templates/billing-form.php create mode 100644 src/modal-checkout/templates/form-coupon.php diff --git a/includes/class-modal-checkout.php b/includes/class-modal-checkout.php index 7acfc4061..691a4820a 100644 --- a/includes/class-modal-checkout.php +++ b/includes/class-modal-checkout.php @@ -503,6 +503,7 @@ public static function wc_get_template( $located, $template_name ) { $custom_templates = [ 'checkout/form-checkout.php' => 'src/modal-checkout/templates/checkout-form.php', 'checkout/thankyou.php' => 'src/modal-checkout/templates/thankyou.php', + 'checkout/form-coupon.php' => 'src/modal-checkout/templates/form-coupon.php', // Replace the login form with the order summary if using the modal checkout. This is // for the case where the reader used an existing email address. 'global/form-login.php' => 'src/modal-checkout/templates/thankyou.php', diff --git a/src/modal-checkout/checkout.scss b/src/modal-checkout/checkout.scss index c37b3e947..88ab326ae 100644 --- a/src/modal-checkout/checkout.scss +++ b/src/modal-checkout/checkout.scss @@ -21,6 +21,13 @@ padding: 12px 16px; font-size: 14px; line-height: 24px; + border-color: #ddd; + } + .button { + font-size: 14px; + background-color: transparent; + color: inherit; + border: 1px solid #dddddd; } #customer_details { .woocommerce-billing-fields { @@ -85,6 +92,7 @@ } #place_order { background-color: var( --newspack-theme-color-primary ); + color: #fff; /* TODO: Fix dynamic contrast */ font-size: 14px; font-weight: 600; display: block; @@ -105,7 +113,9 @@ font-size: 14px; // Prevent relative font size padding: 4px 0; border-color: #dddddd; - white-space: nowrap; + > * { + white-space: nowrap; + } vertical-align: top; } th { @@ -113,8 +123,8 @@ font-weight: 600; text-align: left; } - th:first-child { - width: 100%; + td:last-child { + width: 1%; } tr.cart-subtotal { th { @@ -139,6 +149,16 @@ line-height: 20px; color: #757575; } + .woocommerce-form-coupon { + p { + display: flex; + align-items: center; + input[type='text'] { + margin-right: 8px; + flex-grow: 1; + } + } + } /* Hide reCAPTCHA badge */ .grecaptcha-badge { visibility: hidden !important; diff --git a/src/modal-checkout/index.js b/src/modal-checkout/index.js index 224ec9721..e5c26e8d9 100644 --- a/src/modal-checkout/index.js +++ b/src/modal-checkout/index.js @@ -12,12 +12,15 @@ import './checkout.scss'; const selected = $( 'input[name="payment_method"]:checked' ).val(); $( '.wc_payment_method' ).removeClass( 'selected' ); $( '.wc_payment_method.payment_method_' + selected ).addClass( 'selected' ); + showCouponForm(); + }; + const showCouponForm = () => { + $( '.checkout_coupon' ).show(); }; $( document ).ready( function () { $( document ).on( 'payment_method_selected', handleMethodSelected ); $( document ).on( 'updated_checkout', handleMethodSelected ); $( 'input[name="payment_method"]' ).change( handleMethodSelected ); handleMethodSelected(); - // setTimeout( handleMethodSelected, 1000 ); } ); } )( jQuery ); diff --git a/src/modal-checkout/modal.scss b/src/modal-checkout/modal.scss index fa1b9df34..16167c1f1 100644 --- a/src/modal-checkout/modal.scss +++ b/src/modal-checkout/modal.scss @@ -30,8 +30,8 @@ transform: translate( -50%, -50% ); width: calc( 100vw - 32px ); max-width: 600px; - min-height: 250px; - max-height: calc( 100vh - 32px ); + min-height: 300px; + max-height: 90vh; display: flex; flex-direction: column; justify-content: space-between; @@ -49,6 +49,8 @@ } } &__content { + position: relative; + flex-grow: 1; > * { width: 100%; height: 100%; @@ -61,13 +63,10 @@ background: #fff; border-radius: 5px; display: flex; - height: 100%; justify-content: center; - left: 50%; - opacity: 0.5; position: absolute; - top: 50%; - transform: translate( -50%, -50% ); + top: 0; + bottom: 0; width: 100%; > span { animation: spin 1s infinite linear; @@ -76,6 +75,8 @@ border-radius: 50%; height: 25px; width: 25px; + margin-top: -12.5px; + margin-left: -12.5px; } } &__close { diff --git a/src/modal-checkout/templates/billing-form.php b/src/modal-checkout/templates/billing-form.php deleted file mode 100644 index 61c68f6c4..000000000 --- a/src/modal-checkout/templates/billing-form.php +++ /dev/null @@ -1,43 +0,0 @@ - -
- cart->needs_shipping() ) : ?> - -

- - - -

- - - - - -
- get_checkout_fields( 'billing' ); - - foreach ( $fields as $key => $field ) { - woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); - } - ?> -
- - -
diff --git a/src/modal-checkout/templates/checkout-form.php b/src/modal-checkout/templates/checkout-form.php index 2a648129a..ca75575ed 100644 --- a/src/modal-checkout/templates/checkout-form.php +++ b/src/modal-checkout/templates/checkout-form.php @@ -42,7 +42,9 @@ - +
+ +
diff --git a/src/modal-checkout/templates/form-coupon.php b/src/modal-checkout/templates/form-coupon.php new file mode 100644 index 000000000..00e3fd334 --- /dev/null +++ b/src/modal-checkout/templates/form-coupon.php @@ -0,0 +1,23 @@ + + +

+

+ + +

+
+ From 4cb064ae4994dff03201e05bf2ca00951b1e5f10 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 18:52:48 -0300 Subject: [PATCH 04/53] feat: start front-end 2-step --- includes/class-modal-checkout.php | 38 ++++++++++++++++ src/modal-checkout/checkout.scss | 44 +++++++++++++++---- src/modal-checkout/index.js | 39 ++++++++++++++++ .../templates/checkout-form.php | 2 + 4 files changed, 115 insertions(+), 8 deletions(-) diff --git a/includes/class-modal-checkout.php b/includes/class-modal-checkout.php index 691a4820a..f72023a63 100644 --- a/includes/class-modal-checkout.php +++ b/includes/class-modal-checkout.php @@ -51,6 +51,7 @@ public static function init() { add_filter( 'wcs_place_subscription_order_text', [ __CLASS__, 'order_button_text' ], 1 ); add_filter( 'woocommerce_order_button_text', [ __CLASS__, 'order_button_text' ] ); add_filter( 'option_woocommerce_subscriptions_order_button_text', [ __CLASS__, 'order_button_text' ] ); + add_action( 'woocommerce_before_checkout_form', [ __CLASS__, 'render_before_checkout_form' ] ); add_action( 'woocommerce_checkout_before_terms_and_conditions', [ __CLASS__, 'render_before_terms_and_conditions' ] ); add_action( 'woocommerce_checkout_before_customer_details', [ __CLASS__, 'render_before_customer_details' ] ); add_filter( 'woocommerce_enable_order_notes_field', [ __CLASS__, 'enable_order_notes_field' ] ); @@ -953,6 +954,43 @@ public static function order_button_text( $text ) { return $text; } + /** + * Render before the checkout form. + * + * This will render the order summary card. + */ + public static function render_before_checkout_form() { + if ( ! self::is_modal_checkout() ) { + return; + } + $cart = \WC()->cart; + if ( 1 !== $cart->get_cart_contents_count() ) { + return; + } + ?> +
+ get_cart() as $cart_item_key => $cart_item ) : + $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); + if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) : + ?> +

+ get_name(), $cart_item, $cart_item_key ) . ': '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo wc_get_formatted_cart_item_data( $cart_item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> + get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +

+ +
+ { $( '.checkout_coupon' ).show(); }; + const hideCouponForm = () => { + $( '.checkout_coupon' ).hide(); + }; + const scrollTop = () => { + $( 'html, body' ).animate( + { + scrollTop: 0, + }, + 300 + ); + }; + const editDetails = () => { + scrollTop(); + $( '#customer_details' ).show(); + $( '#after_customer_details' ).hide(); + hideCouponForm(); + }; + const proceedToPay = () => { + scrollTop(); + $( '#customer_details' ).hide(); + $( '#after_customer_details' ).show(); + showCouponForm(); + }; $( document ).ready( function () { $( document ).on( 'payment_method_selected', handleMethodSelected ); $( document ).on( 'updated_checkout', handleMethodSelected ); + $( 'input[name="payment_method"]' ).change( handleMethodSelected ); handleMethodSelected(); + + /** + * If we have a continue order button, treat as a 2-step checkout. + */ + if ( $( '#continue_order' ).length ) { + $( '#continue_order' ).click( ev => { + ev.preventDefault(); + proceedToPay(); + } ); + $( '#edit_details' ).click( ev => { + ev.preventDefault(); + editDetails(); + } ); + editDetails(); + } } ); } )( jQuery ); diff --git a/src/modal-checkout/templates/checkout-form.php b/src/modal-checkout/templates/checkout-form.php index ca75575ed..b92ca4c5a 100644 --- a/src/modal-checkout/templates/checkout-form.php +++ b/src/modal-checkout/templates/checkout-form.php @@ -40,10 +40,12 @@
+
+
From 0af5e2ac7c8eb3b279b18b710ba72d9175de045f Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 19:29:10 -0300 Subject: [PATCH 05/53] fix: style tweaks and button label --- includes/class-modal-checkout.php | 11 +++++++++-- src/modal-checkout/checkout.scss | 26 +++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/includes/class-modal-checkout.php b/includes/class-modal-checkout.php index f72023a63..e5f8db7d2 100644 --- a/includes/class-modal-checkout.php +++ b/includes/class-modal-checkout.php @@ -948,10 +948,17 @@ public static function is_modal_checkout() { * @param string $text The button text. */ public static function order_button_text( $text ) { - if ( self::is_modal_checkout() && method_exists( 'Newspack\Donations', 'is_donation_cart' ) && \Newspack\Donations::is_donation_cart() ) { + if ( ! self::is_modal_checkout() ) { + return $text; + } + if ( method_exists( 'Newspack\Donations', 'is_donation_cart' ) && \Newspack\Donations::is_donation_cart() ) { return __( 'Donate now', 'newspack-blocks' ); } - return $text; + return sprintf( + // Translators: %s is the price. + __( 'Complete transaction: %s', 'newspack-blocks' ), + esc_html( wp_strip_all_tags( \WC()->cart->get_total() ) ) + ); } /** diff --git a/src/modal-checkout/checkout.scss b/src/modal-checkout/checkout.scss index d9d50794f..71b50d3a8 100644 --- a/src/modal-checkout/checkout.scss +++ b/src/modal-checkout/checkout.scss @@ -2,7 +2,10 @@ padding: 24px; h3 { font-size: 16px; - margin: 24px 0 16px; + margin: 0 0 16px; + } + p { + margin: 0 0 16px; } .woocommerce-message, .woocommerce-error, @@ -65,7 +68,13 @@ } } } + #order_review { + margin: 0 0 24px; + } #payment { + .wc_payment_methods { + margin: 0 0 24px; + } .wc_payment_method { border: 1px solid #ddd; border-radius: 6px; @@ -105,10 +114,10 @@ margin-right: 8px; } } + .newspack-cover-fees, .woocommerce-SavedPaymentMethods-saveNew { display: flex; - align-items: center; - margin-top: 16px; + margin: 16px 0 0; input { margin-right: 8px; } @@ -159,10 +168,13 @@ } } } - .woocommerce-privacy-policy-text { - font-size: 14px; - line-height: 20px; - color: #757575; + .woocommerce-terms-and-conditions-wrapper { + margin: 0; + .woocommerce-privacy-policy-text { + font-size: 14px; + line-height: 20px; + color: #757575; + } } .woocommerce-form-coupon { p { From 11d7662e46f7ba7947885c5cd6d0f89013579e61 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Wed, 22 Nov 2023 19:48:25 -0300 Subject: [PATCH 06/53] feat: animate modal in --- includes/class-modal-checkout.php | 2 +- src/modal-checkout/modal.js | 4 ++-- src/modal-checkout/modal.scss | 18 ++++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/includes/class-modal-checkout.php b/includes/class-modal-checkout.php index e5f8db7d2..68afd1d6f 100644 --- a/includes/class-modal-checkout.php +++ b/includes/class-modal-checkout.php @@ -267,7 +267,7 @@ public static function render_modal_markup() { */ $title = apply_filters( 'newspack_blocks_modal_checkout_title', __( 'Complete your transaction', 'newspack-blocks' ) ); ?> -