From 2f0f30369b93b51ac2fdee95c875e5d5b3023c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Mikl=C3=A1=C5=A1?= Date: Tue, 12 Nov 2024 15:40:21 +0100 Subject: [PATCH] Add basic email preview to Emails settings (#52685) * Create slotfill for React component in email settings for email preview * Render email preview iframe * Style email preview container * Add email preview device type toggle * Change email preview width when device type changes * Show email preview subject and sender * Add changelog * Fix linter errors * Add e2e tests for email preview --- .../changelog/52226-email-preview-setting | 5 + .../woocommerce/client/admin/client/index.js | 6 + .../client/settings-email/icon-avatar.svg | 3 + .../settings-email/icon-desktop-active.svg | 4 + .../client/settings-email/icon-desktop.svg | 4 + .../settings-email/icon-mobile-active.svg | 4 + .../client/settings-email/icon-mobile.svg | 4 + .../settings-email-preview-device-type.tsx | 56 +++++++++ .../settings-email-preview-header.tsx | 58 +++++++++ .../settings-email-preview-slotfill.tsx | 66 ++++++++++ .../admin/client/settings-email/style.scss | 113 ++++++++++++++++++ .../admin/client/settings/settings-slots.js | 4 + .../settings/class-wc-settings-emails.php | 15 +++ .../tests/merchant/settings-email.spec.js | 35 ++++++ .../class-wc-settings-emails-test.php | 2 +- 15 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 plugins/woocommerce/changelog/52226-email-preview-setting create mode 100644 plugins/woocommerce/client/admin/client/settings-email/icon-avatar.svg create mode 100644 plugins/woocommerce/client/admin/client/settings-email/icon-desktop-active.svg create mode 100644 plugins/woocommerce/client/admin/client/settings-email/icon-desktop.svg create mode 100644 plugins/woocommerce/client/admin/client/settings-email/icon-mobile-active.svg create mode 100644 plugins/woocommerce/client/admin/client/settings-email/icon-mobile.svg create mode 100644 plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-device-type.tsx create mode 100644 plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-header.tsx create mode 100644 plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-slotfill.tsx create mode 100644 plugins/woocommerce/client/admin/client/settings-email/style.scss create mode 100644 plugins/woocommerce/tests/e2e-pw/tests/merchant/settings-email.spec.js diff --git a/plugins/woocommerce/changelog/52226-email-preview-setting b/plugins/woocommerce/changelog/52226-email-preview-setting new file mode 100644 index 00000000000..d82d18adcf4 --- /dev/null +++ b/plugins/woocommerce/changelog/52226-email-preview-setting @@ -0,0 +1,5 @@ +Significance: patch +Type: add +Comment: Add basic email preview in email settings. Behind a hidden experimental feature, not yet for public use + + diff --git a/plugins/woocommerce/client/admin/client/index.js b/plugins/woocommerce/client/admin/client/index.js index e635b2a2dd5..6542951b4df 100644 --- a/plugins/woocommerce/client/admin/client/index.js +++ b/plugins/woocommerce/client/admin/client/index.js @@ -20,12 +20,14 @@ initRemoteLogging(); */ import './stylesheets/_index.scss'; import { getAdminSetting } from '~/utils/admin-settings'; +import { isFeatureEnabled } from '~/utils/features'; import { PageLayout, EmbedLayout, PrimaryLayout as NoticeArea } from './layout'; import { EmbeddedBodyLayout } from './embedded-body-layout'; import './xstate.js'; import { deriveWpAdminBackgroundColours } from './utils/derive-wp-admin-background-colours'; import { possiblyRenderSettingsSlots } from './settings/settings-slots'; import { registerTaxSettingsConflictErrorFill } from './settings/conflict-error-slotfill'; +import { registerSettingsEmailPreviewFill } from './settings-email/settings-email-preview-slotfill'; import { registerPaymentsSettingsBannerFill } from './payments/payments-settings-banner-slotfill'; import { registerSiteVisibilitySlotFill } from './launch-your-store'; import { @@ -123,6 +125,10 @@ if ( appRoot ) { possiblyRenderOrderAttributionSlot(); registerOrderAttributionSlotFill(); + + if ( isFeatureEnabled( 'email_improvements' ) ) { + registerSettingsEmailPreviewFill(); + } } // Render the CustomerEffortScoreTracksContainer only if diff --git a/plugins/woocommerce/client/admin/client/settings-email/icon-avatar.svg b/plugins/woocommerce/client/admin/client/settings-email/icon-avatar.svg new file mode 100644 index 00000000000..372fdd1bfb5 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/icon-avatar.svg @@ -0,0 +1,3 @@ + + + diff --git a/plugins/woocommerce/client/admin/client/settings-email/icon-desktop-active.svg b/plugins/woocommerce/client/admin/client/settings-email/icon-desktop-active.svg new file mode 100644 index 00000000000..1094b13f149 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/icon-desktop-active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/woocommerce/client/admin/client/settings-email/icon-desktop.svg b/plugins/woocommerce/client/admin/client/settings-email/icon-desktop.svg new file mode 100644 index 00000000000..d3ec4946158 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/icon-desktop.svg @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/woocommerce/client/admin/client/settings-email/icon-mobile-active.svg b/plugins/woocommerce/client/admin/client/settings-email/icon-mobile-active.svg new file mode 100644 index 00000000000..b0ebafb9034 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/icon-mobile-active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/woocommerce/client/admin/client/settings-email/icon-mobile.svg b/plugins/woocommerce/client/admin/client/settings-email/icon-mobile.svg new file mode 100644 index 00000000000..3b75b45a745 --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/icon-mobile.svg @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-device-type.tsx b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-device-type.tsx new file mode 100644 index 00000000000..140866c6bbf --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-device-type.tsx @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import desktopIcon from './icon-desktop.svg'; +import desktopActiveIcon from './icon-desktop-active.svg'; +import mobileIcon from './icon-mobile.svg'; +import mobileActiveIcon from './icon-mobile-active.svg'; + +export const DEVICE_TYPE_DESKTOP = 'desktop'; +export const DEVICE_TYPE_MOBILE = 'mobile'; + +type EmailPreviewDeviceTypeProps = { + deviceType: string; + setDeviceType: ( deviceType: string ) => void; +}; + +export const EmailPreviewDeviceType: React.FC< + EmailPreviewDeviceTypeProps +> = ( { deviceType, setDeviceType } ) => { + const isDesktop = deviceType === DEVICE_TYPE_DESKTOP; + const isMobile = deviceType === DEVICE_TYPE_MOBILE; + const setDesktop = () => setDeviceType( DEVICE_TYPE_DESKTOP ); + const setMobile = () => setDeviceType( DEVICE_TYPE_MOBILE ); + + return ( +
+ + +
+ ); +}; diff --git a/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-header.tsx b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-header.tsx new file mode 100644 index 00000000000..a5094d6117e --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-header.tsx @@ -0,0 +1,58 @@ +/** + * External dependencies + */ +import { SETTINGS_STORE_NAME } from '@woocommerce/data'; +import { __ } from '@wordpress/i18n'; +import { resolveSelect } from '@wordpress/data'; +import { useEffect, useState } from 'react'; + +/** + * Internal dependencies + */ +import avatarIcon from './icon-avatar.svg'; + +type FromSettings = { + woocommerce_email_from_name?: string; + woocommerce_email_from_address?: string; +}; + +export const EmailPreviewHeader: React.FC = () => { + const [ fromName, setFromName ] = useState( '' ); + const [ fromAddress, setFromAddress ] = useState( '' ); + useEffect( () => { + const fetchSettings = async () => { + const { + woocommerce_email_from_name = '', + woocommerce_email_from_address = '', + } = ( + await resolveSelect( SETTINGS_STORE_NAME ).getSettings( + 'email' + ) + ).email as FromSettings; + + setFromName( woocommerce_email_from_name ); + setFromAddress( woocommerce_email_from_address ); + }; + fetchSettings(); + }, [] ); + + return ( +
+

+ Your SampleStore order is now complete +

+
+
+ { +
+
+ { fromName } + { fromAddress } +
+
+
+ ); +}; diff --git a/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-slotfill.tsx b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-slotfill.tsx new file mode 100644 index 00000000000..daae733347a --- /dev/null +++ b/plugins/woocommerce/client/admin/client/settings-email/settings-email-preview-slotfill.tsx @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +import { createSlotFill } from '@wordpress/components'; +import { registerPlugin } from '@wordpress/plugins'; +import { __ } from '@wordpress/i18n'; +import { useState } from 'react'; + +/** + * Internal dependencies + */ +import './style.scss'; +import { SETTINGS_SLOT_FILL_CONSTANT } from '~/settings/settings-slots'; +import { + EmailPreviewDeviceType, + DEVICE_TYPE_DESKTOP, +} from './settings-email-preview-device-type'; +import { EmailPreviewHeader } from './settings-email-preview-header'; + +const { Fill } = createSlotFill( SETTINGS_SLOT_FILL_CONSTANT ); + +type EmailPreviewFillProps = { + previewUrl: string; +}; + +const EmailPreviewFill: React.FC< EmailPreviewFillProps > = ( { + previewUrl, +} ) => { + const [ deviceType, setDeviceType ] = + useState< string >( DEVICE_TYPE_DESKTOP ); + return ( + +
+
+ +
+
+ +