Use new tabs in Settings

[MAILPOET-2775]
This commit is contained in:
Jan Jakeš
2020-06-11 15:56:26 +02:00
committed by Veljko V
parent a6b98202e7
commit 67212cd9c9
9 changed files with 205 additions and 269 deletions

View File

@@ -81,7 +81,7 @@ const RoutedTabs = ({
</RouterAwareTabs>
)}
/>
<Redirect to={`/${activeKey}`} />
<Redirect to={`${routerPrefix}${activeKey}`} />
</Switch>
</>
);

View File

@@ -1,4 +1,3 @@
export { default as Tabs } from './tabs';
export { default as Label } from './label';
export { default as Inputs } from './inputs';
export { default as SaveButton } from './save_button';

View File

@@ -1,29 +0,0 @@
import classnames from 'classnames';
import React, { ReactNode } from 'react';
import { Link } from 'react-router-dom';
import MailPoet from 'mailpoet';
type Props = {
name: string
current: string
children: ReactNode
automationId: string
}
export default (props: Props) => (
<Link
to={`/${props.name}`}
onClick={() => trackTabClicked(props.name)}
data-automation-id={props.automationId}
className={classnames('nav-tab', { 'nav-tab-active': props.name === props.current })}
>
{props.children}
</Link>
);
const trackTabClicked = (tab: string) => {
MailPoet.trackEvent('User has clicked a tab in Settings', {
'MailPoet Free version': (window as any).mailpoet_version,
'Tab ID': tab,
});
};

View File

@@ -1,60 +0,0 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import { t } from 'common/functions';
import { useSelector } from 'settings/store/hooks';
import TabLink from './tab_link';
export default () => {
const { pathname } = useLocation();
const [, current] = pathname.split('/');
const hasWooCommerce = useSelector('hasWooCommerce')();
return (
<h2 className="nav-tab-wrapper">
<TabLink
name="basics"
current={current}
automationId="basic_settings_tab"
>
{t('basicsTab')}
</TabLink>
<TabLink
name="signup"
current={current}
automationId="signup_settings_tab"
>
{t('signupConfirmationTab')}
</TabLink>
<TabLink
name="mta"
current={current}
automationId="send_with_settings_tab"
>
{t('sendWithTab')}
</TabLink>
{hasWooCommerce && (
<TabLink
name="woocommerce"
current={current}
automationId="woocommerce_settings_tab"
>
{t('wooCommerceTab')}
</TabLink>
)}
<TabLink
name="advanced"
current={current}
automationId="settings-advanced-tab"
>
{t('advancedTab')}
</TabLink>
<TabLink
name="premium"
current={current}
automationId="activation_settings_tab"
>
{t('keyActivationTab')}
</TabLink>
</h2>
);
};

View File

@@ -1,16 +1,13 @@
import React from 'react';
import 'parsleyjs';
import ReactDOM from 'react-dom';
import { HashRouter } from 'react-router-dom';
import { GlobalContext, useGlobalContextValue } from 'context';
import { initStore } from './store';
import Settings from './settings';
const Entry = () => (
<GlobalContext.Provider value={useGlobalContextValue(window)}>
<HashRouter>
<Settings />
</HashRouter>
<Settings />
</GlobalContext.Provider>
);

View File

@@ -2,6 +2,5 @@ export { default as Basics } from './basics/basics';
export { default as Advanced } from './advanced/advanced';
export { default as KeyActivation } from './key_activation/key_activation';
export { default as SendWith } from './send_with/send_with';
export { default as OtherSendingMethods } from './send_with/other/other_sending_methods';
export { default as SignupConfirmation } from './signup_confirmation/signup_confirmation';
export { default as WooCommerce } from './woo_commerce/woo_commerce';

View File

@@ -1,163 +1,11 @@
import React from 'react';
import classnames from 'classnames';
import ReactStringReplace from 'react-string-replace';
import { useSelector, useAction, useSetting } from 'settings/store/hooks';
import { MssStatus } from 'settings/store/types';
import { t } from 'common/functions';
import { Link } from 'react-router-dom';
import { useParams } from 'react-router-dom';
import SendWithChoice from './send_with_choice';
import OtherSendingMethods from './other/other_sending_methods';
export default function SendWith() {
const isNewUser = useSelector('isNewUser')();
const isMssActive = useSelector('isMssActive')();
const [key] = useSetting('mta', 'mailpoet_api_key');
const { mssStatus } = useSelector('getKeyActivationState')();
const isMssKeyValid = mssStatus !== null && mssStatus !== MssStatus.INVALID;
const freePlanUrl = (window as any).mailpoet_free_plan_url;
const setSetting = useAction('setSetting');
const saveSettings = useAction('saveSettings');
const activateMss = async () => {
await setSetting(['mta_group'], 'mailpoet');
await setSetting(['mta', 'method'], 'MailPoet');
await setSetting(['mta', 'mailpoet_api_key'], key);
await setSetting(['signup_confirmation', 'enabled'], '1');
return saveSettings();
};
return (
<ul className="mailpoet_sending_methods">
<li
data-group="mailpoet"
className={classnames({
mailpoet_active: isMssActive,
mailpoet_invalid_key: !isMssKeyValid,
})}
>
<div className="mailpoet_sending_method_description">
<h3>{t('mssTitle')}</h3>
<div className="mailpoet_description">
{isMssActive && (
<span id="mailpoet_sending_method_active_text">
<strong>{t('youreSendingWithMss')}</strong>
</span>
)}
{!isMssActive
&& (
<span id="mailpoet_sending_method_inactive_text">
<strong>{t('solveSendingProblems')}</strong>
</span>
)}
<ul className="sending-method-benefits mailpoet_success">
<li className="mailpoet_success_item">{t('mssBenefit1')}</li>
<li className="mailpoet_success_item">{t('mssBenefit2')}</li>
<li className="mailpoet_success_item">{t('mssBenefit3')}</li>
<li className="mailpoet_success_item">{t('mssBenefit4')}</li>
<li className="mailpoet_success_item">{t('mssBenefit5')}</li>
</ul>
<p className="mailpoet_sending_methods_help">
<a
target="_blank"
rel="noopener noreferrer"
data-beacon-article="5a3d4c260428631938003802"
href="https://kb.mailpoet.com/article/235-video-guide-sending-options"
className={classnames('mailpoet_badge mailpoet_badge_video', {
mailpoet_badge_video_grey: !isNewUser,
})}
>
<span className="dashicons dashicons-format-video" />
{t('seeVideo')}
</a>
</p>
</div>
</div>
<div className={classnames('mailpoet_status', {
mailpoet_invalid_key: !isMssActive || !isMssKeyValid,
})}
>
{isMssActive && isMssKeyValid
&& (
<div className="mailpoet_activated">
<span>{t('activated')}</span>
</div>
)}
<div className="mailpoet_actions">
{!isMssKeyValid && (
<div className="mailpoet_invalid_key">
<a className="button-primary" href={freePlanUrl} rel="noopener noreferrer" target="_blank">{t('freeUpto')}</a>
{' '}
{t('or')}
{' '}
{ReactStringReplace(t('enterYourKey'), /\[link\](.*?)\[\/link\]/g,
(match, i) => (
<Link key={i} to="/premium">{match}</Link>
))}
</div>
)}
{!isMssActive && isMssKeyValid && (
<div className="mailpoet_valid_key">
<button
type="button"
onClick={activateMss}
className="mailpoet_sending_service_activate button-primary"
>
{t('activate')}
</button>
</div>
)}
</div>
</div>
</li>
<li
data-group="other"
className={classnames({ mailpoet_active: !isMssActive })}
>
<div className="mailpoet_sending_method_description">
<h3>{t('otherTitle')}</h3>
<div className="mailpoet_description">
<strong>{t('otherDescription')}</strong>
<ul className="sending-method-benefits mailpoet_error">
<li className="mailpoet_error_item">{t('otherCons1')}</li>
<li className="mailpoet_error_item">{t('otherCons2')}</li>
<li className="mailpoet_error_item">{t('otherCons3')}</li>
<li className="mailpoet_error_item">
{ReactStringReplace(t('otherCons4'), /\[link\](.*?)\[\/link\]/g,
(match, i) => (
<a
key={i}
target="_blank"
rel="noopener noreferrer"
href="https://wordpress.org/plugins/bounce-handler-mailpoet/"
>
{match}
</a>
))}
</li>
</ul>
</div>
</div>
<div className="mailpoet_status">
<span>{t('activated')}</span>
<div className="mailpoet_actions">
{isMssActive && (
<Link
className="button-primary mailpoet_other_sending_method_action"
to="/mta/other"
>
{t('activate')}
</Link>
)}
{!isMssActive && (
<Link
className="button-secondary mailpoet_other_sending_method_action"
to="/mta/other"
>
{t('configure')}
</Link>
)}
</div>
</div>
</li>
</ul>
);
const { subPage } = useParams();
return subPage === 'other'
? <OtherSendingMethods />
: <SendWithChoice />;
}

View File

@@ -0,0 +1,163 @@
import React from 'react';
import classnames from 'classnames';
import ReactStringReplace from 'react-string-replace';
import { useSelector, useAction, useSetting } from 'settings/store/hooks';
import { MssStatus } from 'settings/store/types';
import { t } from 'common/functions';
import { Link } from 'react-router-dom';
export default function SendWithChoice() {
const isNewUser = useSelector('isNewUser')();
const isMssActive = useSelector('isMssActive')();
const [key] = useSetting('mta', 'mailpoet_api_key');
const { mssStatus } = useSelector('getKeyActivationState')();
const isMssKeyValid = mssStatus !== null && mssStatus !== MssStatus.INVALID;
const freePlanUrl = (window as any).mailpoet_free_plan_url;
const setSetting = useAction('setSetting');
const saveSettings = useAction('saveSettings');
const activateMss = async () => {
await setSetting(['mta_group'], 'mailpoet');
await setSetting(['mta', 'method'], 'MailPoet');
await setSetting(['mta', 'mailpoet_api_key'], key);
await setSetting(['signup_confirmation', 'enabled'], '1');
return saveSettings();
};
return (
<ul className="mailpoet_sending_methods">
<li
data-group="mailpoet"
className={classnames({
mailpoet_active: isMssActive,
mailpoet_invalid_key: !isMssKeyValid,
})}
>
<div className="mailpoet_sending_method_description">
<h3>{t('mssTitle')}</h3>
<div className="mailpoet_description">
{isMssActive && (
<span id="mailpoet_sending_method_active_text">
<strong>{t('youreSendingWithMss')}</strong>
</span>
)}
{!isMssActive
&& (
<span id="mailpoet_sending_method_inactive_text">
<strong>{t('solveSendingProblems')}</strong>
</span>
)}
<ul className="sending-method-benefits mailpoet_success">
<li className="mailpoet_success_item">{t('mssBenefit1')}</li>
<li className="mailpoet_success_item">{t('mssBenefit2')}</li>
<li className="mailpoet_success_item">{t('mssBenefit3')}</li>
<li className="mailpoet_success_item">{t('mssBenefit4')}</li>
<li className="mailpoet_success_item">{t('mssBenefit5')}</li>
</ul>
<p className="mailpoet_sending_methods_help">
<a
target="_blank"
rel="noopener noreferrer"
data-beacon-article="5a3d4c260428631938003802"
href="https://kb.mailpoet.com/article/235-video-guide-sending-options"
className={classnames('mailpoet_badge mailpoet_badge_video', {
mailpoet_badge_video_grey: !isNewUser,
})}
>
<span className="dashicons dashicons-format-video" />
{t('seeVideo')}
</a>
</p>
</div>
</div>
<div className={classnames('mailpoet_status', {
mailpoet_invalid_key: !isMssActive || !isMssKeyValid,
})}
>
{isMssActive && isMssKeyValid
&& (
<div className="mailpoet_activated">
<span>{t('activated')}</span>
</div>
)}
<div className="mailpoet_actions">
{!isMssKeyValid && (
<div className="mailpoet_invalid_key">
<a className="button-primary" href={freePlanUrl} rel="noopener noreferrer" target="_blank">{t('freeUpto')}</a>
{' '}
{t('or')}
{' '}
{ReactStringReplace(t('enterYourKey'), /\[link\](.*?)\[\/link\]/g,
(match, i) => (
<Link key={i} to="/premium">{match}</Link>
))}
</div>
)}
{!isMssActive && isMssKeyValid && (
<div className="mailpoet_valid_key">
<button
type="button"
onClick={activateMss}
className="mailpoet_sending_service_activate button-primary"
>
{t('activate')}
</button>
</div>
)}
</div>
</div>
</li>
<li
data-group="other"
className={classnames({ mailpoet_active: !isMssActive })}
>
<div className="mailpoet_sending_method_description">
<h3>{t('otherTitle')}</h3>
<div className="mailpoet_description">
<strong>{t('otherDescription')}</strong>
<ul className="sending-method-benefits mailpoet_error">
<li className="mailpoet_error_item">{t('otherCons1')}</li>
<li className="mailpoet_error_item">{t('otherCons2')}</li>
<li className="mailpoet_error_item">{t('otherCons3')}</li>
<li className="mailpoet_error_item">
{ReactStringReplace(t('otherCons4'), /\[link\](.*?)\[\/link\]/g,
(match, i) => (
<a
key={i}
target="_blank"
rel="noopener noreferrer"
href="https://wordpress.org/plugins/bounce-handler-mailpoet/"
>
{match}
</a>
))}
</li>
</ul>
</div>
</div>
<div className="mailpoet_status">
<span>{t('activated')}</span>
<div className="mailpoet_actions">
{isMssActive && (
<Link
className="button-primary mailpoet_other_sending_method_action"
to="/mta/other"
>
{t('activate')}
</Link>
)}
{!isMssActive && (
<Link
className="button-secondary mailpoet_other_sending_method_action"
to="/mta/other"
>
{t('configure')}
</Link>
)}
</div>
</div>
</li>
</ul>
);
}

View File

@@ -1,8 +1,10 @@
import React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import MailPoet from 'mailpoet';
import Notices from 'notices/notices.jsx';
import Loading from 'common/loading';
import { t } from 'common/functions';
import RoutedTabs from 'common/tabs/routed_tabs';
import Tab from 'common/tabs/tab';
import {
Advanced,
Basics,
@@ -10,29 +12,46 @@ import {
SendWith,
SignupConfirmation,
WooCommerce,
OtherSendingMethods,
} from './pages';
import Tabs from './components/tabs';
import { useSelector } from './store/hooks';
const trackTabSwitched = (tabKey: string) => {
MailPoet.trackEvent('User has clicked a tab in Settings', {
'MailPoet Free version': MailPoet.version,
'Tab ID': tabKey,
});
};
export default function Settings() {
const isSaving = useSelector('isSaving')();
const hasWooCommerce = useSelector('hasWooCommerce')();
return (
<>
{isSaving && <Loading />}
<Notices />
<h1 className="title">{t('settings')}</h1>
<Tabs />
<Switch>
<Route path="/basics" component={Basics} />
<Route path="/signup" component={SignupConfirmation} />
<Route exact path="/mta" component={SendWith} />
<Route path="/mta/other" component={OtherSendingMethods} />
<Route path="/woocommerce" component={WooCommerce} />
<Route path="/advanced" component={Advanced} />
<Route path="/premium" component={KeyActivation} />
<Redirect to="/basics" />
</Switch>
<RoutedTabs activeKey="basics" onSwitch={(tabKey: string) => trackTabSwitched(tabKey)}>
<Tab key="basics" title={t('basicsTab')} automationId="basic_settings_tab">
<Basics />
</Tab>
<Tab key="signup" title={t('signupConfirmationTab')} automationId="signup_settings_tab">
<SignupConfirmation />
</Tab>
<Tab key="mta" route="mta/:subPage?" title={t('sendWithTab')} automationId="send_with_settings_tab">
<SendWith />
</Tab>
{hasWooCommerce && (
<Tab key="woocommerce" title={t('wooCommerceTab')} automationId="woocommerce_settings_tab">
<WooCommerce />
</Tab>
)}
<Tab key="advanced" title={t('advancedTab')} automationId="settings-advanced-tab">
<Advanced />
</Tab>
<Tab key="premium" title={t('keyActivationTab')} automationId="activation_settings_tab">
<KeyActivation />
</Tab>
</RoutedTabs>
</>
);
}