Add different sections for welcome screen
[MAILPOET-4536]
This commit is contained in:
@ -0,0 +1,171 @@
|
||||
:root {
|
||||
--menu-width: 0;
|
||||
|
||||
@media screen and (min-width: 783px) {
|
||||
--menu-width: 36px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 961px) {
|
||||
--menu-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin full-width {
|
||||
margin-left: calc(-50vw + var(--menu-width) / 2 + 50%);
|
||||
padding-left: 104px;
|
||||
padding-right: 104px;
|
||||
width: calc(100vw - var(--menu-width));
|
||||
}
|
||||
|
||||
.mailpoet-automation-section {
|
||||
h2 {
|
||||
font-size: 23px;
|
||||
font-weight: 400;
|
||||
line-height: 32px;
|
||||
margin: 0;
|
||||
padding: 0 0 8px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
margin: 0;
|
||||
padding: 0 0 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-automation-section-hero {
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-top: -20px;
|
||||
padding: 65px;
|
||||
|
||||
@include full-width;
|
||||
|
||||
.mailpoet-automation-preheading {
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
letter-spacing: .2px;
|
||||
line-height: 16px;
|
||||
margin-bottom: 65px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
> div {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-section-templates {
|
||||
padding: 48px 84px;
|
||||
|
||||
.mailpoet-section-template-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 40px;
|
||||
|
||||
li {
|
||||
max-width: 336px;
|
||||
|
||||
button {
|
||||
background: #fff;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 0;
|
||||
color: #1d2327;
|
||||
cursor: pointer;
|
||||
height: auto;
|
||||
padding: 24px;
|
||||
text-align: left;
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.components-button {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
text-underline-offset: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-section-build-your-own {
|
||||
background: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 64px;
|
||||
|
||||
@include full-width;
|
||||
|
||||
ol {
|
||||
list-style: decimal-leading-zero;
|
||||
margin: 0;
|
||||
max-width: 373px;
|
||||
padding: 0;
|
||||
|
||||
.mailpoet-section-build-list-button {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> li {
|
||||
border-bottom: 1px solid #dcdcde;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 16px;
|
||||
|
||||
&::marker {
|
||||
color: #ff5301;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
p {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.open {
|
||||
p {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mailpoet-section-build-list-button {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
|
||||
.mailpoet-option-button-main {
|
||||
border-radius: 2px 0 0 2px;
|
||||
margin-right: 2px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.mailpoet-option-button-opener {
|
||||
@ -38,4 +38,14 @@
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.mailpoet-option-button-item {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #1d2327;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
// automation listing
|
||||
|
||||
@import './components-automation-listing/sections';
|
||||
@import './components-automation-listing/listing';
|
||||
@import './components-automation-listing/header';
|
||||
@import './components-automation-listing/search';
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
mailpoet/assets/img/automations/sections/design-your-email.png
Normal file
BIN
mailpoet/assets/img/automations/sections/design-your-email.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
mailpoet/assets/img/automations/sections/hero.png
Normal file
BIN
mailpoet/assets/img/automations/sections/hero.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
BIN
mailpoet/assets/img/automations/sections/start-engaging.png
Normal file
BIN
mailpoet/assets/img/automations/sections/start-engaging.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -1,10 +1,8 @@
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { TopBarWithBeamer } from 'common/top_bar/top_bar';
|
||||
import { plusIcon } from 'common/button/icon/plus';
|
||||
import { Button, Flex, Popover, SlotFillProvider } from '@wordpress/components';
|
||||
import { Popover, SlotFillProvider } from '@wordpress/components';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { initializeApi, useMutation } from './api';
|
||||
import { registerTranslations } from './i18n';
|
||||
import { createStore, storeName } from './listing/store';
|
||||
@ -12,33 +10,28 @@ import { AutomationListing } from './listing';
|
||||
import { registerApiErrorHandler } from './listing/api-error-handler';
|
||||
import { Notices } from './listing/components/notices';
|
||||
import { WorkflowListingNotices } from './listing/workflow-listing-notices';
|
||||
import { Onboarding } from './onboarding';
|
||||
import { BuildYourOwnSection, HeroSection, TemplatesSection } from './sections';
|
||||
import {
|
||||
CreateEmptyWorkflowButton,
|
||||
CreateWorkflowFromTemplateButton,
|
||||
} from './testing';
|
||||
import { MailPoet } from '../mailpoet';
|
||||
|
||||
function Content(): JSX.Element {
|
||||
const count = useSelect((select) => select(storeName).getWorkflowCount());
|
||||
return count > 0 ? <AutomationListing /> : <Onboarding />;
|
||||
const content = count > 0 ? <AutomationListing /> : <HeroSection />;
|
||||
return (
|
||||
<>
|
||||
{content}
|
||||
<TemplatesSection />
|
||||
<BuildYourOwnSection />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Workflows(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<TopBarWithBeamer />
|
||||
<Flex className="mailpoet-automation-listing-heading">
|
||||
<h1 className="wp-heading-inline">{__('Automations', 'mailpoet')}</h1>
|
||||
<Button
|
||||
href={MailPoet.urls.automationTemplates}
|
||||
icon={plusIcon}
|
||||
variant="primary"
|
||||
className="mailpoet-add-new-button"
|
||||
>
|
||||
{__('New automation', 'mailpoet')}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Notices />
|
||||
<Content />
|
||||
</>
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
export function Onboarding(): JSX.Element {
|
||||
return (
|
||||
<div className="mailpoet-automation onboarding">
|
||||
<img src="" alt="" />
|
||||
<h1>{__('Scale your business with advanced automations', 'mailpoet')}</h1>
|
||||
<p>
|
||||
{__(
|
||||
'Automated workflow allows you to set up a chain of interactions with your subscribers with less efforts. You control all the flow with a visual scheme and a set of goals. Try it!',
|
||||
'mailpoet',
|
||||
)}
|
||||
</p>
|
||||
<a href="#" className="button secondary">
|
||||
{__('Learn more', 'mailpoet')}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
import { useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { MailPoet } from '../../mailpoet';
|
||||
|
||||
export function BuildYourOwnSection(): JSX.Element {
|
||||
const [itemOpen, setItemOpen] = useState('start-with-a-trigger');
|
||||
const list: { slug: string; title: string; text: string; image: string }[] = [
|
||||
{
|
||||
slug: 'start-with-a-trigger',
|
||||
title: __('Start with a trigger', 'mailpoet'),
|
||||
text: __(
|
||||
'Deliver relevant messages to your customers based on who they are and how they interact with your business.',
|
||||
'mailpoet',
|
||||
),
|
||||
image: `${MailPoet.urls.imageAssets}automations/sections/start-with-a-trigger.png`,
|
||||
},
|
||||
{
|
||||
slug: 'customize-your-workflow',
|
||||
title: __('Customize your workflow', 'mailpoet'),
|
||||
text: __(
|
||||
'Choose steps and create a custom journey to best suit your needs.',
|
||||
'mailpoet',
|
||||
),
|
||||
image: `${MailPoet.urls.imageAssets}automations/sections/customize-your-workflow.png`,
|
||||
},
|
||||
{
|
||||
slug: 'design-your-email',
|
||||
title: __('Design your email', 'mailpoet'),
|
||||
text: __(
|
||||
'Modify one of our pre-made email templates or create your own design.',
|
||||
'mailpoet',
|
||||
),
|
||||
image: `${MailPoet.urls.imageAssets}automations/sections/design-your-email.png`,
|
||||
},
|
||||
{
|
||||
slug: 'start-engaging',
|
||||
title: __('Start engaging', 'mailpoet'),
|
||||
text: __(
|
||||
'Activate the automation and start engaging with your customers as they interact with your business.',
|
||||
'mailpoet',
|
||||
),
|
||||
image: `${MailPoet.urls.imageAssets}automations/sections/start-engaging.png`,
|
||||
},
|
||||
];
|
||||
|
||||
const selectedItem = list.filter((item) => item.slug === itemOpen)[0];
|
||||
|
||||
return (
|
||||
<section className="mailpoet-automation-section mailpoet-section-build-your-own">
|
||||
<div>
|
||||
<h2>{__('Build your own automation workflows', 'mailpoet')}</h2>
|
||||
<p>
|
||||
{__(
|
||||
'Create customized email sequences with our new automation editor.',
|
||||
'mailpoet',
|
||||
)}
|
||||
</p>
|
||||
<ol>
|
||||
{list.map((item) => (
|
||||
<li
|
||||
key={item.slug}
|
||||
className={itemOpen === item.slug ? 'open' : ''}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setItemOpen(item.slug)}
|
||||
className="mailpoet-section-build-list-button"
|
||||
>
|
||||
{item.title}
|
||||
</button>
|
||||
<p>{item.text}</p>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
<img src={selectedItem.image} alt={selectedItem.title} />
|
||||
</section>
|
||||
);
|
||||
}
|
41
mailpoet/assets/js/src/automation/sections/hero-section.tsx
Normal file
41
mailpoet/assets/js/src/automation/sections/hero-section.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Hooks } from '../../hooks';
|
||||
import { OptionButton } from '../components/option-button';
|
||||
import { MailPoet } from '../../mailpoet';
|
||||
|
||||
export function HeroSection(): JSX.Element {
|
||||
const buttonActions: JSX.Element[] = Hooks.applyFilters(
|
||||
'mailpoet.automation.hero.actions',
|
||||
[],
|
||||
);
|
||||
return (
|
||||
<section className="mailpoet-automation-section mailpoet-automation-section-hero">
|
||||
<div>
|
||||
<span className="mailpoet-automation-preheading">
|
||||
{__('Automations', 'mailpoet')}
|
||||
</span>
|
||||
<h1>{__('Better engagement begins with automation', 'mailpoet')}</h1>
|
||||
<p>
|
||||
{__(
|
||||
'Send emails that inform, reward, and engage your audience through powerful segmenting, scheduling, and design tools.',
|
||||
'mailpoet',
|
||||
)}
|
||||
</p>
|
||||
|
||||
<OptionButton
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
window.location.href = MailPoet.urls.automationTemplates;
|
||||
}}
|
||||
title={__('Start with a template', 'mailpoet')}
|
||||
>
|
||||
{buttonActions}
|
||||
</OptionButton>
|
||||
</div>
|
||||
<img
|
||||
src={`${MailPoet.urls.imageAssets}automations/sections/hero.png`}
|
||||
alt={__('Welcome', 'mailpoet')}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
3
mailpoet/assets/js/src/automation/sections/index.tsx
Normal file
3
mailpoet/assets/js/src/automation/sections/index.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
export { HeroSection } from './hero-section';
|
||||
export { TemplatesSection } from './templates-section';
|
||||
export { BuildYourOwnSection } from './build-your-own-section';
|
@ -0,0 +1,33 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { MailPoet } from '../../mailpoet';
|
||||
import { workflowTemplates } from '../templates/config';
|
||||
import { TemplateListItem } from '../templates/components/template-list-item';
|
||||
|
||||
export function TemplatesSection(): JSX.Element {
|
||||
const templates = workflowTemplates.slice(0, 3);
|
||||
|
||||
return (
|
||||
<section className="mailpoet-automation-section mailpoet-section-templates">
|
||||
<h2>{__('Start with essentials', 'mailpoet')}</h2>
|
||||
<p>
|
||||
{__(
|
||||
'Choose from our list of pre-made templates and make it your own',
|
||||
'mailpoet',
|
||||
)}
|
||||
</p>
|
||||
<ul className="mailpoet-section-template-list">
|
||||
{templates.map((template) => (
|
||||
<TemplateListItem
|
||||
key={template.slug}
|
||||
template={template}
|
||||
heading="h3"
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
<Button variant="link" href={MailPoet.urls.automationTemplates}>
|
||||
{__('Browse all templates →', 'mailpoet')}
|
||||
</Button>
|
||||
</section>
|
||||
);
|
||||
}
|
@ -8,9 +8,11 @@ import { Notice } from '../../../notices/notice';
|
||||
|
||||
type TemplateListItemProps = {
|
||||
template: WorkflowTemplate;
|
||||
heading?: 'h2' | 'h3';
|
||||
};
|
||||
export function TemplateListItem({
|
||||
template,
|
||||
heading,
|
||||
}: TemplateListItemProps): JSX.Element {
|
||||
const [createWorkflowFromTemplate, { loading, error, data }] = useMutation(
|
||||
'workflows/create-from-template',
|
||||
@ -41,6 +43,7 @@ export function TemplateListItem({
|
||||
);
|
||||
}
|
||||
|
||||
const headingTag = heading ?? 'h2';
|
||||
return (
|
||||
<li className="mailpoet-automation-template-list-item">
|
||||
{notice}
|
||||
@ -50,7 +53,9 @@ export function TemplateListItem({
|
||||
void createWorkflowFromTemplate();
|
||||
}}
|
||||
>
|
||||
<h2>{template.name} →</h2>
|
||||
{headingTag === 'h3' && <h3>{template.name} →</h3>}
|
||||
{headingTag === 'h2' && <h2>{template.name} →</h2>}
|
||||
|
||||
<p>{template.description}</p>
|
||||
</Button>
|
||||
</li>
|
||||
|
@ -3,9 +3,11 @@
|
||||
namespace MailPoet\AdminPages\Pages;
|
||||
|
||||
use MailPoet\AdminPages\PageRenderer;
|
||||
use MailPoet\Automation\Engine\Data\WorkflowTemplate;
|
||||
use MailPoet\Automation\Engine\Migrations\Migrator;
|
||||
use MailPoet\Automation\Engine\Storage\WorkflowStorage;
|
||||
use MailPoet\Form\AssetsController;
|
||||
use MailPoet\Automation\Engine\Storage\WorkflowTemplateStorage;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class Automation {
|
||||
@ -24,18 +26,23 @@ class Automation {
|
||||
/** @var WorkflowStorage */
|
||||
private $workflowStorage;
|
||||
|
||||
/** @var WorkflowTemplateStorage */
|
||||
private $templateStorage;
|
||||
|
||||
public function __construct(
|
||||
AssetsController $assetsController,
|
||||
Migrator $migrator,
|
||||
PageRenderer $pageRenderer,
|
||||
WPFunctions $wp,
|
||||
WorkflowStorage $workflowStorage
|
||||
WorkflowStorage $workflowStorage,
|
||||
WorkflowTemplateStorage $templateStorage
|
||||
) {
|
||||
$this->assetsController = $assetsController;
|
||||
$this->migrator = $migrator;
|
||||
$this->pageRenderer = $pageRenderer;
|
||||
$this->wp = $wp;
|
||||
$this->workflowStorage = $workflowStorage;
|
||||
$this->templateStorage = $templateStorage;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
@ -50,6 +57,12 @@ class Automation {
|
||||
'nonce' => $this->wp->wpCreateNonce('wp_rest'),
|
||||
],
|
||||
'workflowCount' => $this->workflowStorage->getWorkflowCount(),
|
||||
'templates' => array_map(
|
||||
function(WorkflowTemplate $template): array {
|
||||
return $template->toArray();
|
||||
},
|
||||
$this->templateStorage->getTemplates()
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
<script type="text/javascript">
|
||||
var mailpoet_automation_api = <%= json_encode(api) %>;
|
||||
var mailpoet_workflow_count = <%= json_encode(workflowCount) %>;
|
||||
var mailpoet_automation_templates = <%= json_encode(templates) %>;
|
||||
</script>
|
||||
<% endblock %>
|
||||
|
||||
|
Reference in New Issue
Block a user