From 3c824053d7b44c2d80f925bdd3cdf58940f9769b Mon Sep 17 00:00:00 2001 From: Seghir Nadir Date: Wed, 7 Dec 2022 16:52:02 +0100 Subject: [PATCH] Show notice if merchant has legacy local pickup enabled alongside the new pickup (https://github.com/woocommerce/woocommerce-blocks/pull/7842) * add notice when there are existing enabled legacy local pickups * Fix PHP warning * Link though to the settings page * Fix setting save * Enabling this will produce duplicate options at checkout. Co-authored-by: Mike Jolley --- .../pickup-location/general-settings.tsx | 32 ++++++- .../pickup-location/settings-context.tsx | 4 + .../shipping-methods/pickup-location/types.ts | 5 ++ .../shipping-methods/pickup-location/utils.ts | 33 ++++++-- .../shared-components/settings-card/index.tsx | 7 +- .../src/Shipping/ShippingController.php | 83 ++++++++++++++----- 6 files changed, 129 insertions(+), 35 deletions(-) diff --git a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/general-settings.tsx b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/general-settings.tsx index 75cde629771..9ff33643a25 100644 --- a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/general-settings.tsx +++ b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/general-settings.tsx @@ -2,6 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { createInterpolateElement, useState } from '@wordpress/element'; import { ADMIN_URL } from '@woocommerce/settings'; import { CHECKOUT_PAGE_ID } from '@woocommerce/block-settings'; import { @@ -9,8 +10,9 @@ import { SelectControl, TextControl, ExternalLink, + Notice, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import styled from '@emotion/styled'; /** * Internal dependencies @@ -35,13 +37,39 @@ const GeneralSettingsDescription = () => ( ); +const StyledNotice = styled( Notice )` + margin-left: 0; + margin-right: 0; +`; + const GeneralSettings = () => { - const { settings, setSettingField } = useSettingsContext(); + const { settings, setSettingField, readOnlySettings } = + useSettingsContext(); const [ showCosts, setShowCosts ] = useState( !! settings.cost ); return ( + { readOnlySettings.hasLegacyPickup && ( + + { createInterpolateElement( + __( + 'Enabling this will produce duplicate options at checkout. Remove the local pickup shipping method from your shipping zones.', + 'woo-gutenberg-products-block' + ), + { + a: ( + // eslint-disable-next-line jsx-a11y/anchor-has-content + + ), + } + ) } + + ) } ( { settings: defaultSettings, + readOnlySettings: defaultReadyOnlySettings, setSettingField: () => () => void null, pickupLocations: [], setPickupLocations: () => void null, @@ -155,6 +158,7 @@ export const SettingsProvider = ( { const settingsData = { settings, setSettingField, + readOnlySettings, pickupLocations, setPickupLocations, toggleLocation, diff --git a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/types.ts b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/types.ts index a04b31135d4..86184fbcb41 100644 --- a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/types.ts +++ b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/types.ts @@ -30,8 +30,13 @@ export type ShippingMethodSettings = { cost: string; }; +export type ReadOnlySettings = { + hasLegacyPickup: boolean; +}; + export type SettingsContextType = { settings: ShippingMethodSettings; + readOnlySettings: ReadOnlySettings; setSettingField: ( field: keyof ShippingMethodSettings ) => ( value: unknown ) => void; diff --git a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/utils.ts b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/utils.ts index 7b203d2a764..9bb45df6410 100644 --- a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/utils.ts +++ b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/pickup-location/utils.ts @@ -2,7 +2,6 @@ * External dependencies */ import { cleanForSlug } from '@wordpress/url'; -import { getSetting } from '@woocommerce/settings'; /** * Internal dependencies @@ -25,20 +24,35 @@ export const indexLocationsById = ( }; export const defaultSettings = { - enabled: 'yes', + enabled: true, title: '', tax_status: 'taxable', cost: '', }; +export const defaultReadyOnlySettings = { + hasLegacyPickup: false, +}; +declare global { + const hydratedScreenSettings: { + pickupLocationSettings: { + enabled: string; + title: string; + tax_status: string; + cost: string; + }; + pickupLocations: PickupLocation[]; + readonlySettings: typeof defaultReadyOnlySettings; + }; +} + export const getInitialSettings = (): ShippingMethodSettings => { - const settings = getSetting( - 'pickupLocationSettings', - defaultSettings - ) as typeof defaultSettings; + const settings = hydratedScreenSettings.pickupLocationSettings; return { - enabled: settings?.enabled === 'yes', + enabled: settings?.enabled + ? settings?.enabled === 'yes' + : defaultSettings.enabled, title: settings?.title || defaultSettings.title, tax_status: settings?.tax_status || defaultSettings.tax_status, cost: settings?.cost || defaultSettings.cost, @@ -46,4 +60,7 @@ export const getInitialSettings = (): ShippingMethodSettings => { }; export const getInitialPickupLocations = (): SortablePickupLocation[] => - indexLocationsById( getSetting( 'pickupLocations', [] ) ); + indexLocationsById( hydratedScreenSettings.pickupLocations || [] ); + +export const readOnlySettings = + hydratedScreenSettings.readonlySettings || defaultReadyOnlySettings; diff --git a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/shared-components/settings-card/index.tsx b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/shared-components/settings-card/index.tsx index 7c9fba6fa5c..aab68b4d56d 100644 --- a/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/shared-components/settings-card/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/extensions/shipping-methods/shared-components/settings-card/index.tsx @@ -2,6 +2,7 @@ * External dependencies */ import { Card, CardBody } from '@wordpress/components'; +import type { ReactNode } from 'react'; import styled from '@emotion/styled'; const StyledCard = styled( Card )` @@ -9,6 +10,8 @@ const StyledCard = styled( Card )` `; const StyledCardBody = styled( CardBody )` + padding: 24px; + // increasing the specificity of the styles to override the Gutenberg ones &.is-size-medium.is-size-medium { padding: 24px; @@ -21,7 +24,7 @@ const StyledCardBody = styled( CardBody )` > * { margin-top: 0; - margin-bottom: 1em; + margin-bottom: 1.5em; // fixing the spacing on the inputs and their help text, to ensure it is consistent &:last-child { @@ -52,7 +55,7 @@ const SettingsCard = ( { children, ...props }: { - children: ( JSX.Element | null )[]; + children: ReactNode; } ): JSX.Element => ( { children } diff --git a/plugins/woocommerce-blocks/src/Shipping/ShippingController.php b/plugins/woocommerce-blocks/src/Shipping/ShippingController.php index 569d6b105f4..d7eed080712 100644 --- a/plugins/woocommerce-blocks/src/Shipping/ShippingController.php +++ b/plugins/woocommerce-blocks/src/Shipping/ShippingController.php @@ -40,29 +40,6 @@ class ShippingController { * Initialization method. */ public function init() { - // @todo This should be moved inline for the settings page only. - $this->asset_data_registry->add( - 'pickupLocationSettings', - get_option( 'woocommerce_pickup_location_settings', [] ), - true - ); - $this->asset_data_registry->add( - 'pickupLocations', - function() { - $locations = get_option( 'pickup_location_pickup_locations', [] ); - $formatted = []; - foreach ( $locations as $location ) { - $formatted[] = [ - 'name' => $location['name'], - 'address' => $location['address'], - 'details' => $location['details'], - 'enabled' => wc_string_to_bool( $location['enabled'] ), - ]; - } - return $formatted; - }, - true - ); if ( is_admin() ) { $this->asset_data_registry->add( 'countryStates', @@ -74,6 +51,7 @@ class ShippingController { } add_action( 'rest_api_init', [ $this, 'register_settings' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'hydrate_client_settings' ] ); add_action( 'woocommerce_load_shipping_methods', array( $this, 'register_local_pickup' ) ); add_filter( 'woocommerce_local_pickup_methods', array( $this, 'register_local_pickup_method' ) ); add_filter( 'woocommerce_customer_taxable_address', array( $this, 'filter_taxable_address' ) ); @@ -170,6 +148,65 @@ class ShippingController { ); } + /** + * Hydrate client settings + */ + public function hydrate_client_settings() { + $locations = get_option( 'pickup_location_pickup_locations', [] ); + + $formatted_pickup_locations = []; + foreach ( $locations as $location ) { + $formatted_pickup_locations[] = [ + 'name' => $location['name'], + 'address' => $location['address'], + 'details' => $location['details'], + 'enabled' => wc_string_to_bool( $location['enabled'] ), + ]; + } + + $has_legacy_pickup = false; + + // Get all shipping zones. + $shipping_zones = \WC_Shipping_Zones::get_zones( 'admin' ); + $international_shipping_zone = new \WC_Shipping_Zone( 0 ); + + // Loop through each shipping zone. + foreach ( $shipping_zones as $shipping_zone ) { + // Get all registered rates for this shipping zone. + $shipping_methods = $shipping_zone['shipping_methods']; + // Loop through each registered rate. + foreach ( $shipping_methods as $shipping_method ) { + if ( 'local_pickup' === $shipping_method->id && 'yes' === $shipping_method->enabled ) { + $has_legacy_pickup = true; + break 2; + } + } + } + + foreach ( $international_shipping_zone->get_shipping_methods( true ) as $shipping_method ) { + if ( 'local_pickup' === $shipping_method->id ) { + $has_legacy_pickup = true; + break; + } + } + + $settings = array( + 'pickupLocationSettings' => get_option( 'woocommerce_pickup_location_settings', [] ), + 'pickupLocations' => $formatted_pickup_locations, + 'readonlySettings' => array( + 'hasLegacyPickup' => $has_legacy_pickup, + ), + ); + + wp_add_inline_script( + 'wc-shipping-method-pickup-location', + sprintf( + 'var hydratedScreenSettings = %s;', + wp_json_encode( $settings ) + ), + 'before' + ); + } /** * Load admin scripts. */