Skip to content
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

Add survey modal on WooPayments deactivation #8757

Merged
merged 21 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1468b86
Add deactivation survey modal
mordeth May 2, 2024
c73a7e4
Fix updateOption throws errors
mordeth May 2, 2024
5e90267
Add changelog
mordeth May 2, 2024
8d9f668
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 2, 2024
1f9fea7
Update wrong option permission added to the list
mordeth May 7, 2024
662bcb3
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 7, 2024
e9119c3
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 8, 2024
1be9f6b
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 8, 2024
7e36e23
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 13, 2024
474ffed
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 15, 2024
e9e4f1e
Add wp-components dependency to plugins page
mordeth May 20, 2024
88cc4e9
Minor docs updates
mordeth May 20, 2024
7911335
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 20, 2024
621cf8e
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 20, 2024
9e62d41
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth May 20, 2024
8473e73
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth Jun 3, 2024
b5d575b
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth Jun 4, 2024
6ccf8f8
Doesn't show exit survey 7 days after deactivation
mordeth Jun 4, 2024
b661ab5
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth Jun 4, 2024
f2c0bd0
Fix hovering X button on modal shows tooltip
mordeth Jun 4, 2024
a42d6c5
Merge branch 'develop' into add/1527-survey-modal-on-deactivation
mordeth Jun 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/add-1527-survey-modal-on-deactivation
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add a feedback survey modal upon deactivation.
50 changes: 50 additions & 0 deletions client/plugins-page/deactivation-survey/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* External dependencies
*/
import React, { useState } from 'react';
import { __ } from '@wordpress/i18n';
import { Modal } from '@wordpress/components';

/**
* Internal dependencies
*/
import './style.scss';
import Loadable from 'wcpay/components/loadable';
import WooPaymentsIcon from 'assets/images/woopayments.svg?asset';

const PluginDisableSurvey = ( { onRequestClose } ) => {
const [ isLoading, setIsLoading ] = useState( true );

return (
<Modal
title={
<img
src={ WooPaymentsIcon }
alt={ __( 'WooPayments Logo', 'woocommerce-payments' ) }
className="woopayments-disable-survey-logo"
/>
}
isDismissible={ true }
shouldCloseOnClickOutside={ false } // Should be false because of the iframe.
shouldCloseOnEsc={ true }
onRequestClose={ onRequestClose }
className="woopayments-disable-survey"
>
<Loadable isLoading={ isLoading }>
<iframe
title={ __(
'WooPayments Disable Survey',
'woocommerce-payments'
) }
src="https://automattic.survey.fm/woopayments-exit-feedback"
className="woopayments-disable-survey-iframe"
onLoad={ () => {
setIsLoading( false );
} }
/>
</Loadable>
</Modal>
);
};

export default PluginDisableSurvey;
38 changes: 38 additions & 0 deletions client/plugins-page/deactivation-survey/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.woopayments-disable-survey {
@media ( min-width: 960px ) {
max-height: calc( 100% - 120px );
}

.components-modal__content {
padding: 0;
overflow: hidden;
}

&-iframe {
width: 100%;
height: 100%;

@media ( min-width: 600px ) {
width: 600px;
height: 650px;
}
}

&-logo {
height: 40px;
}
}

/**
* There is a bug with the Modal component that when the close X is hovered or focused, a tooltip
* appears outside of the view of the modal causing scrollbars. This is a work around to hide the
* tooltip until the bug is fixed.
* TODO: remove rule ones bug is closed
* https://github.com/WordPress/gutenberg/issues/15434
*/
.components-modal__content
.components-modal__header
.components-button
.components-tooltip {
display: none;
}
108 changes: 108 additions & 0 deletions client/plugins-page/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* External dependencies
*/
import React, { useState, useEffect, useCallback } from 'react';
import { useDispatch } from '@wordpress/data';
import ReactDOM from 'react-dom';
import { OPTIONS_STORE_NAME } from '@woocommerce/data';

/**
* Internal dependencies
*/
import PluginDisableSurvey from './deactivation-survey';

const PluginsPage = () => {
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
const [ modalOpen, setModalOpen ] = useState( false );
const surveyModalTimestamp =
window.wcpayPluginsSettings?.exitSurveyLastShown ?? null;

const deactivationLink = document.querySelector(
'#deactivate-woocommerce-payments, #deactivate-woocommerce-payments-dev'
); // ID set by WP on the deactivation link.

const deactivatePlugin = useCallback( () => {
// Abort if the deactivation link is not present.
if ( deactivationLink === null ) {
return null;
}

// Deactivate plugin
window.location.href = deactivationLink.getAttribute( 'href' );
}, [ deactivationLink ] );

const showModal = useCallback( () => {
setModalOpen( true );
}, [ setModalOpen ] );

const closeModal = async () => {
setModalOpen( false );

const currentDate = new Date();

// Update modal dismissed option.
await updateOptions( {
wcpay_exit_survey_last_shown: currentDate,
} );

window.wcpayPluginsSettings.exitSurveyLastShown = currentDate;

// Deactivate plugin
deactivatePlugin();
};

const isModalDismissed = useCallback( () => {
if ( surveyModalTimestamp ) {
const date1 = new Date( surveyModalTimestamp );
const date2 = new Date();
const diffTime = Math.abs( date2 - date1 );
const diffDays = Math.ceil( diffTime / ( 1000 * 60 * 60 * 24 ) );

if ( diffDays < 7 ) {
return true;
}
}

return false;
}, [ surveyModalTimestamp ] );

const handleLinkClick = useCallback(
( e ) => {
e.preventDefault();
showModal();
},
[ showModal ]
);

useEffect( () => {
// If the survey is dismissed skip event listeners.
if ( isModalDismissed() ) {
return null;
}

// Abort if the deactivation link is not present.
if ( deactivationLink === null ) {
return null;
}

// Handle click event.
deactivationLink.addEventListener( 'click', handleLinkClick );

return () => {
deactivationLink.removeEventListener( 'click', handleLinkClick );
};
}, [ isModalDismissed, deactivationLink, handleLinkClick ] );

return (
<>
{ ! isModalDismissed() && modalOpen && (
<PluginDisableSurvey onRequestClose={ closeModal } />
) }
</>
);
};

ReactDOM.render(
<PluginsPage />,
document.querySelector( '#woopayments-plugins-page-app' )
);
57 changes: 57 additions & 0 deletions includes/admin/class-wc-payments-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,17 @@ public function register_payments_scripts() {
WC_Payments::get_file_version( 'dist/payment-gateways.css' ),
'all'
);

WC_Payments::register_script_with_dependencies( 'WCPAY_PLUGINS_PAGE', 'dist/plugins-page', [ 'wp-api-request' ] );
wp_set_script_translations( 'WCPAY_PLUGINS_PAGE', 'woocommerce-payments' );

WC_Payments_Utils::register_style(
'WCPAY_PLUGINS_PAGE',
plugins_url( 'dist/plugins-page.css', WCPAY_PLUGIN_FILE ),
[ 'wp-components', 'wc-components' ],
WC_Payments::get_file_version( 'dist/plugins-page.css' ),
'all'
);
}

/**
Expand Down Expand Up @@ -669,6 +680,23 @@ public function enqueue_payments_scripts() {
}

$screen = get_current_screen();

// Only enqueue the scripts on the plugins page.
if ( in_array( $screen->id, [ 'plugins' ], true ) ) {
// Localize before actually enqueuing to avoid unnecessary settings generation.
// Most importantly, the destructive error transient handling.
wp_localize_script(
'WCPAY_PLUGINS_PAGE',
'wcpayPluginsSettings',
$this->get_plugins_page_js_settings()
);

wp_enqueue_script( 'WCPAY_PLUGINS_PAGE' );
wp_enqueue_style( 'WCPAY_PLUGINS_PAGE' );

add_action( 'admin_footer', [ $this, 'load_plugins_page_wrapper' ] );
}

if ( in_array( $screen->id, [ 'shop_order', 'woocommerce_page_wc-orders' ], true ) ) {
$order = wc_get_order();

Expand Down Expand Up @@ -719,6 +747,22 @@ public function enqueue_payments_scripts() {
}
}

/**
* Outputs the wrapper for the plugin modal
* Contents are loaded by React script
*
* @return void
*/
public function load_plugins_page_wrapper() {
wc_get_template(
'plugins-page/plugins-page-wrapper.php',
[],
'',
WCPAY_ABSPATH . 'templates/'
);
}


/**
* Get the WCPay settings to be sent to JS.
*
Expand Down Expand Up @@ -872,6 +916,19 @@ private function get_js_settings(): array {
return apply_filters( 'wcpay_js_settings', $this->wcpay_js_settings );
}

/**
* Get the WCPay plugins page settings to be sent to JS.
*
* @return array
*/
private function get_plugins_page_js_settings(): array {
$plugins_page_settings = [
'exitSurveyLastShown' => get_option( 'wcpay_exit_survey_last_shown', null ),
];

return apply_filters( 'wcpay_plugins_page_js_settings', $plugins_page_settings );
}

/**
* Helper function to retrieve enabled UPE payment methods.
*
Expand Down
1 change: 1 addition & 0 deletions includes/class-wc-payments.php
Original file line number Diff line number Diff line change
Expand Up @@ -1828,6 +1828,7 @@ public static function add_wcpay_options_to_woocommerce_permissions_list( $permi
'wcpay_onboarding_eligibility_modal_dismissed',
'wcpay_next_deposit_notice_dismissed',
'wcpay_duplicate_payment_method_notices_dismissed',
'wcpay_exit_survey_dismissed',
],
true
);
Expand Down
24 changes: 24 additions & 0 deletions templates/plugins-page/plugins-page-wrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* WooPayments wrapper markup rendered on plugins page.
*
* This template can be overridden by copying it to yourtheme/woocommerce/plugins-page/plugins-page-wrapper.php
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://woocommerce.com/document/template-structure/
* @package WooCommerce\Payments\Templates\PluginsPage
* @version 1.0.0
*/

defined( 'ABSPATH' ) || exit;
?>
<div id="woopayments-plugins-page-app">
<!--
The content is rendered from React.
-->
</div>
1 change: 1 addition & 0 deletions webpack/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = {
'./client/subscription-product-onboarding/toast.js',
'product-details': './client/product-details/index.js',
'cart-block': './client/cart/blocks/index.js',
'plugins-page': './client/plugins-page/index.js',
},
// Override webpack public path dynamically on every entry.
// Required for chunks loading to work on sites with JS concatenation.
Expand Down
Loading