Skip to content

Commit

Permalink
Woo Installer: Landing page redesign re-deploy (#58179)
Browse files Browse the repository at this point in the history
* Add WoopLandingPage component

* Add cta header component

* Remove extra comment

* Style landing page

* Hide/Show Navigation Button when scrolling past the CTA Button

* Re-organize components and use Types

* Add SetupNotices to the new landing page

* Add some responsive CSS and remove mixin

* Remove style import and use rem

* Add WoopLandingPage component

* Add cta header component

* Remove extra comment

* Style landing page

* Adds WaveMasonry component to the woop landing page

* Rendering only images

* changes cta-header to 1 column layout on mobile

* Update client/components/masonry-wave/index.jsx

* Clean up merge conflicts

* Clean up landing-page prop

* Clean up spacing, scroll

* Add WooCommerce title

* cta-header uses css-grid 1 column layout and centers content on mobile

* adds @automattic/viewport-react and fixes key related warnings

- Adds @automattic/viewport-react to the MasonryWave component to conditionally render different layouts on mobile and web.
- Fixes missing key warnings on the MasonryWave component.

* renaming cta images to a more descriptive name | removing unused cta images

Co-authored-by: Rolando Perez <me@rolilink.com>
Co-authored-by: Louis Laugesen <louis.laugesen@gmail.com>
  • Loading branch information
3 people authored and nelsonec87 committed Dec 9, 2021
1 parent 9b92885 commit f0cb7ae
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 29 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions client/components/cta-section/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Button } from '@automattic/components';
import styled from '@emotion/styled';
import { TranslateResult } from 'i18n-calypso';

const Container = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
min-height: 500px;
column-gap: 2em;
row-gap: 2em;
@media ( max-width: 660px ) {
grid-template-columns: 1fr;
}
`;

const CtaContainer = styled.div`
justify-self: start;
@media ( max-width: 660px ) {
margin-bottom: 4em;
text-align: center;
}
`;

const ContentContainer = styled.div`
justify-self: end;
`;

const Headline = styled.h3`
font-size: 16px;
padding-bottom: 10px;
`;

const Title = styled.h4`
font-family: Recoleta;
color: var( --studio-gray-90 );
font-size: 2.81rem;
line-height: 1.19;
padding-bottom: 1em;
`;

interface Props {
title?: TranslateResult;
headline?: TranslateResult;
buttonText: TranslateResult;
buttonAction: () => void;
ctaRef?: React.RefObject< HTMLButtonElement >;
}

const CtaSection: React.FunctionComponent< Props > = ( props ) => {
const { children, title, headline, buttonText, buttonAction, ctaRef } = props;
return (
<Container>
<CtaContainer>
<Headline>{ title }</Headline>
<Title>{ headline }</Title>
<Button primary onClick={ buttonAction } ref={ ctaRef }>
{ buttonText }
</Button>
</CtaContainer>
<ContentContainer>{ children }</ContentContainer>
</Container>
);
};

export default CtaSection;
41 changes: 38 additions & 3 deletions client/components/fixed-navigation-header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
import { useEffect, useRef } from '@wordpress/element';
import { ReactNode } from 'react';
import Breadcrumb from 'calypso/components/breadcrumb';

Expand Down Expand Up @@ -55,16 +56,50 @@ interface Props {
className?: string;
children?: ReactNode;
navigationItems: { label: string; href?: string }[];
contentRef?: React.RefObject< HTMLElement >;
}

const FixedNavigationHeader: React.FunctionComponent< Props > = ( props ) => {
const { id, className, children, navigationItems } = props;
const { id, className, children, navigationItems, contentRef } = props;
const actionsRef = useRef< HTMLDivElement >( null );
const headerRef = useRef< HTMLElement >( null );

useEffect( () => {
if ( ! contentRef ) {
return;
}

const handleScroll = () => {
const headerHeight = headerRef?.current?.getBoundingClientRect().height;
const offset =
contentRef.current && headerHeight ? contentRef.current.offsetTop - headerHeight : 0;
const scrollPosition = window.scrollY;
const actionElement = actionsRef?.current;

if ( ! actionElement ) {
return;
}

if ( offset > 0 && scrollPosition < offset ) {
actionElement.style.visibility = 'hidden';
} else {
actionElement.style.visibility = 'visible';
}
};

handleScroll();

window.addEventListener( 'scroll', handleScroll );
return () => {
window.removeEventListener( 'scroll', handleScroll );
};
}, [ contentRef ] );

return (
<Header id={ id } className={ className }>
<Header id={ id } className={ className } ref={ headerRef }>
<Container>
<Breadcrumb items={ navigationItems } />
<ActionsContainer>{ children }</ActionsContainer>
<ActionsContainer ref={ actionsRef }>{ children }</ActionsContainer>
</Container>
</Header>
);
Expand Down
66 changes: 66 additions & 0 deletions client/components/masonry-wave/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import './style.scss';
import { useDesktopBreakpoint } from '@automattic/viewport-react';

// fills the columns with images LTR to imitate the CSS grid behavior
const fillColumnsWithImages = ( amountOfColumns, images ) => {
const columns = Array( amountOfColumns );
let columnIndex = 0;

images.forEach( ( image ) => {
if ( columnIndex === amountOfColumns ) {
columnIndex = 0;
}

if ( ! columns[ columnIndex ] ) {
columns[ columnIndex ] = [];
}

columns[ columnIndex ].push( image );

columnIndex++;
} );

return columns;
};

const MasonryWaveElement = ( props ) => {
const { image } = props;

return (
<img src={ image?.src } alt={ image?.alt ?? 'alt text' } className="masonry-wave__element" />
);
};

const MasonryWaveColumn = ( props ) => {
const { images } = props;

return (
<div className="masonry-wave__column">
{ images.map( ( image, index ) => (
<MasonryWaveElement key={ `masonry-wave__row-${ index }` } image={ image } />
) ) }
</div>
);
};

const MasonryWave = ( props ) => {
const isDesktop = useDesktopBreakpoint();

const { numberOfColumns, images } = props;
const numberOfDesktopColumns = numberOfColumns?.desktop ?? 2;
const numberOfMobileColumns = numberOfColumns?.mobile ?? numberOfDesktopColumns;
const amountOfColumns = isDesktop ? numberOfDesktopColumns : numberOfMobileColumns;
const columns = fillColumnsWithImages( amountOfColumns, images );

const styles = { '--masonry-wave--amountOfColumns': amountOfColumns };

return (
<div className=" masonry-wave__container" style={ styles }>
{ columns.map( ( col, index ) => (
<MasonryWaveColumn key={ `masonry-wave__col-${ index }` } images={ col } />
) ) }
</div>
);
};

export default MasonryWave;
23 changes: 23 additions & 0 deletions client/components/masonry-wave/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@import '@wordpress/base-styles/breakpoints';
@import '@wordpress/base-styles/mixins';

.masonry-wave__container {
display: grid;
grid-template-columns: repeat(var(--masonry-wave--amountOfColumns), 1fr);
grid-auto-rows: minmax(min-content, max-content);
column-gap: 0.75rem;
.masonry-wave__column {
&:nth-child(even) {
padding-top: 1.5rem;
}

.masonry-wave__element {
box-shadow: 2px 2px 10px #aaa;
margin-bottom: 0.75rem;

&:last-child {
margin-bottom: 0;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { getAllPlugins as getAllWporgPlugins } from 'calypso/state/plugins/wporg
import hasSitePendingAutomatedTransfer from 'calypso/state/selectors/has-site-pending-automated-transfer';
import { getSelectedSiteWithFallback, getSiteWooCommerceUrl } from 'calypso/state/sites/selectors';
import { recordTrack } from '../lib/analytics';
import WoopLandingPage from '../woop/landing-page';
import SetupHeader from './setup/header';
import SetupNotices from './setup/notices';

Expand Down Expand Up @@ -477,29 +478,6 @@ class RequiredPluginsInstallView extends Component {
}
};

renderConfirmScreen = () => {
const { translate } = this.props;
return (
<div className="dashboard__setup-wrapper setup__wrapper">
<SetupNotices />
<div className="card dashboard__setup-confirm">
<SetupHeader
imageSource={ '/calypso/images/extensions/woocommerce/woocommerce-setup.svg' }
imageWidth={ 160 }
title={ translate( 'Have something to sell?' ) }
subtitle={ translate(
'You can sell your products right on your site and ship them to customers in a snap!'
) }
>
<Button onClick={ this.startSetup } primary>
{ translate( 'Set up my store!' ) }
</Button>
</SetupHeader>
</div>
</div>
);
};

getTotalSeconds = () => {
const { hasPendingAT } = this.props;

Expand Down Expand Up @@ -597,7 +575,12 @@ class RequiredPluginsInstallView extends Component {
const { engineState, progress, totalSeconds } = this.state;

if ( ! hasPendingAT && 'CONFIRMING' === engineState ) {
return this.renderConfirmScreen();
return (
<>
<SetupNotices />
<WoopLandingPage startSetup={ this.startSetup } />
</>
);
}

if ( 'DONEFAILURE' === engineState ) {
Expand Down
5 changes: 3 additions & 2 deletions client/my-sites/woocommerce/main.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { translate } from 'i18n-calypso';
import { useSelector } from 'react-redux';
import DocumentHead from 'calypso/components/data/document-head';
import QueryJetpackPlugins from 'calypso/components/data/query-jetpack-plugins';
import Main from 'calypso/components/main';
import { isLoaded as arePluginsLoaded } from 'calypso/state/plugins/installed/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import RequiredPluginsInstallView from './dashboard/required-plugins-install-view';
import WooCommerceColophon from './woocommerce-colophon';

function WooCommerce() {
const siteId = useSelector( getSelectedSiteId );
Expand All @@ -19,10 +20,10 @@ function WooCommerce() {
return (
<div className="woocommerce">
<Main class="main" wideLayout>
<DocumentHead title={ translate( 'WooCommerce' ) } />
<QueryJetpackPlugins siteIds={ [ siteId ] } />
{ areInstalledPluginsLoadedIntoState && <RequiredPluginsInstallView /> }
</Main>
<WooCommerceColophon />
</div>
);
}
Expand Down
43 changes: 43 additions & 0 deletions client/my-sites/woocommerce/woop/landing-page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Button } from '@automattic/components';
import { useRef } from '@wordpress/element';
import { translate } from 'i18n-calypso';
import './style.scss';
import Image01 from 'calypso/assets/images/woocommerce/woop-cta-image01.jpeg';
import Image02 from 'calypso/assets/images/woocommerce/woop-cta-image02.jpeg';
import Image03 from 'calypso/assets/images/woocommerce/woop-cta-image03.jpeg';
import Image04 from 'calypso/assets/images/woocommerce/woop-cta-image04.jpeg';
import CtaSection from 'calypso/components/cta-section';
import FixedNavigationHeader from 'calypso/components/fixed-navigation-header';
import MasonryWave from 'calypso/components/masonry-wave';

interface Props {
startSetup: () => void;
}

const images = [ { src: Image01 }, { src: Image02 }, { src: Image03 }, { src: Image04 } ];

const WoopLandingPage: React.FunctionComponent< Props > = ( { startSetup } ) => {
const navigationItems = [ { label: 'WooCommerce', href: `/woocommerce-installation` } ];
const ctaRef = useRef( null );

return (
<div className="woop__landing-page">
<FixedNavigationHeader navigationItems={ navigationItems } contentRef={ ctaRef }>
<Button onClick={ startSetup } primary>
{ translate( 'Set up my store!' ) }
</Button>
</FixedNavigationHeader>
<CtaSection
title={ translate( 'Have something to sell?' ) }
headline={ translate( 'Build exactly the eCommerce website you want.' ) }
buttonText={ translate( 'Set up my store!' ) }
buttonAction={ startSetup }
ctaRef={ ctaRef }
>
<MasonryWave images={ images } />
</CtaSection>
</div>
);
};

export default WoopLandingPage;
3 changes: 3 additions & 0 deletions client/my-sites/woocommerce/woop/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body.is-section-woocommerce-installation.theme-default.color-scheme {
--color-surface-backdrop: var( --studio-white );
}

0 comments on commit f0cb7ae

Please sign in to comment.