setAttributes( { email: value } ) }
/>
{ submissionError && (
{ sprintf(
/* translators: %s: Email address. */
_x(
'Something went wrong and we couldn’t receive your support request. Please try again later or send us an email to %s.',
'user',
'nelio-content'
),
'support@neliosoftware.com'
) }
) }
setReason( { value: 'other', details: '' } )
}
>
{ _x( 'Back', 'command', 'nelio-content' ) }
{ isTicketSubmitting
? _x( 'Submitting…', 'text', 'nelio-content' )
: _x(
'Submit and Keep Plugin',
'command',
'nelio-content'
) }
>
);
};
const DefaultDeactivationBody = ( {
isLocked,
isSubscribed,
mainActionLabel,
cleanAndDeactivate,
reason,
setReason,
}: ModalState ): JSX.Element => (
<>
{ _x(
'If you have a moment, please share why you are deactivating Nelio Content:',
'user',
'nelio-content'
) }
setReason( { value, details: '' } )
}
extraValue={ reason.details }
onExtraChange={ ( details ) => setReason( { ...reason, details } ) }
disabled={ isLocked }
/>
{ isSubscribed && (
{ _x(
'Please keep in mind your subscription to Nelio Content will remain active after removing the plugin from this site. If you want to unsubscribe from our service, you can do so from the plugin’s Account page before you deactivate the plugin.',
'user',
'nelio-content'
) }
) }
{ isLocked ? (
) : (
cleanAndDeactivate() }
>
{ _x( 'Just Delete Data', 'command', 'nelio-content' ) }
) }
cleanAndDeactivate(
! reason.details
? reason.value
: `${ reason.value }: ${ reason.details }`
)
}
>
{ mainActionLabel }
>
);
// =====
// HOOKS
// =====
type ModalState = ReturnType< typeof useModalState >;
const useModalState = ( {
cleanNonce,
deactivationUrl,
isSubscribed,
}: DeactivationActionProps ) => {
const [ state, setState ] = useState( INIT_STATE );
const redirect = () => {
window.location.href = deactivationUrl;
};
const openModal = () =>
setState( {
...INIT_STATE,
isModalOpen: true,
} );
const closeModal = () =>
setState( {
...INIT_STATE,
isModalOpen: false,
} );
const deactivate = () => {
setState( {
...state,
reason: INIT_STATE.reason,
isDeactivating: true,
isLocked: true,
} );
redirect();
};
const lock = ( isLocked = true ) => setState( { ...state, isLocked } );
const cleanAndDeactivate = ( reason?: string ): void => {
setState( { ...state, isDeactivating: true } );
void apiFetch( {
path: '/nelio-content/v1/plugin/clean',
method: 'POST',
data: { reason, _nonce: cleanNonce },
} ).then(
redirect, // on success
closeModal // on error
);
};
const setReason = ( reason: State[ 'reason' ] ) =>
setState( { ...state, reason } );
const mainActionLabel =
'temporary-deactivation' === state.reason.value
? getDeactivationLabel( state.isDeactivating )
: getCleanAndDeactivateLabel( state.isDeactivating );
return {
isModalOpen: state.isModalOpen,
openModal,
closeModal,
isDeactivating: state.isDeactivating,
isSubscribed,
mainActionLabel,
deactivate,
cleanAndDeactivate,
isLocked: state.isLocked,
lock,
reason: state.reason,
setReason,
};
};
const getDeactivationLabel = ( isDeactivating: boolean ) =>
isDeactivating
? _x( 'Deactivating…', 'text', 'nelio-content' )
: _x( 'Deactivate', 'command', 'nelio-content' );
const getCleanAndDeactivateLabel = ( isDeleting: boolean ) =>
isDeleting
? _x( 'Deleting Data…', 'text', 'nelio-content' )
: _x( 'Submit and Delete Data', 'command', 'nelio-content' );
// ====
// DATA
// ====
const INIT_STATE: State = {
isModalOpen: false,
isDeactivating: false,
isLocked: false,
reason: {
value: 'temporary-deactivation',
details: '',
},
};
const INIT_CONTACT_FORM_STATE: ContactFormState = {
isTicketSubmitting: false,
email: '',
description: '',
submissionError: false,
};
const DEACTIVATION_MODES: ReadonlyArray< {
readonly value: State[ 'reason' ][ 'value' ];
readonly label: string;
} > = [
{
value: 'temporary-deactivation',
label: _x( 'It’s a temporary deactivation', 'text', 'nelio-content' ),
},
{
value: 'clean-stuff',
label: _x(
'Delete Nelio Content’s data and deactivate plugin',
'text',
'nelio-content'
),
},
];
const DEACTIVATION_REASONS: ReadonlyArray< {
readonly value: State[ 'reason' ][ 'value' ];
readonly label: string;
readonly extra?: string;
} > = [
{
value: 'plugin-no-longer-needed',
label: _x( 'I no longer need the plugin', 'text', 'nelio-content' ),
},
{
value: 'plugin-doesnt-work',
label: _x(
'I couldn’t get the plugin to work',
'text',
'nelio-content'
),
},
{
value: 'better-plugin-found',
label: _x( 'I found a better plugin', 'text', 'nelio-content' ),
extra: _x( 'What’s the plugin’s name?', 'text', 'nelio-content' ),
},
{
value: 'other',
label: _x( 'Other', 'text', 'nelio-content' ),
extra: _x( 'Please share the reason…', 'user', 'nelio-content' ),
},
];
function getDescription(
description: string,
siteId: Uuid,
homeUrl: Url,
isSubscribed: boolean
): string {
const div = document.createElement( 'div' );
const br = () => document.createElement( 'br' );
const extra = document.createElement( 'strong' );
extra.textContent = 'Additional Information';
const ul = document.createElement( 'ul' );
const li1 = document.createElement( 'li' );
li1.textContent = `Site ID: ${ siteId }`;
const li2 = document.createElement( 'li' );
li2.textContent = `Site URL: ${ homeUrl }`;
const li3 = document.createElement( 'li' );
li3.textContent = `Subscribed: ${ isSubscribed ? 'yes' : 'no' }`;
ul.appendChild( li1 );
ul.appendChild( li2 );
ul.appendChild( li3 );
trim( description )
.split( /\n+/ )
.forEach( ( t ) => {
const p = document.createTextNode( t );
div.appendChild( p );
div.appendChild( br() );
div.appendChild( br() );
} );
div.appendChild( extra );
div.appendChild( br() );
div.appendChild( ul );
return div.innerHTML;
}