-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A4A: Implement Hosting page v3 header. (#97162)
* Initial header implementation. * Implement navigation tab. * Add Hosting content from v2. * Move hero banner at the layout top wrapper. * Add some gap on the header content * Fix hovering style for selected tab. * Hide title on scroll. * Add new migration offer banner. * Hide migration offer banner on scroll. * Make the top at sticky position. * Fix flickering with animation. * Minor Migration offer banner improvement. * Additional improvement and bug fixes. * Minor optimization on compact mode on scroll. * Address PR comments.
- Loading branch information
1 parent
c780b16
commit f944e0e
Showing
12 changed files
with
735 additions
and
9 deletions.
There are no files selected for viewing
120 changes: 120 additions & 0 deletions
120
client/a8c-for-agencies/components/a4a-migration-offer-v3/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { Button } from '@wordpress/components'; | ||
import { Icon, chevronDown } from '@wordpress/icons'; | ||
import clsx from 'clsx'; | ||
import { useTranslate } from 'i18n-calypso'; | ||
import { useCallback } from 'react'; | ||
import { useDispatch } from 'calypso/state'; | ||
import { recordTracksEvent } from 'calypso/state/analytics/actions'; | ||
import { CONTACT_URL_FOR_MIGRATION_OFFER_HASH_FRAGMENT } from '../a4a-contact-support-widget'; | ||
import { A4A_MIGRATIONS_OVERVIEW_LINK } from '../sidebar-menu/lib/constants'; | ||
import SimpleList from '../simple-list'; | ||
|
||
import './style.scss'; | ||
|
||
type Props = { | ||
isExpanded: boolean; | ||
onToggleView: () => void; | ||
}; | ||
|
||
const MigrationOfferV3 = ( { isExpanded, onToggleView }: Props ) => { | ||
const translate = useTranslate(); | ||
const dispatch = useDispatch(); | ||
|
||
const onContactUsClick = useCallback( | ||
( e: React.MouseEvent< HTMLButtonElement > ) => { | ||
e.stopPropagation(); | ||
dispatch( recordTracksEvent( 'a4a_migration_offer_contact_us_click' ) ); | ||
}, | ||
[ dispatch ] | ||
); | ||
|
||
const onSeeFullTermClick = useCallback( () => { | ||
dispatch( recordTracksEvent( 'a4a_migration_offer_see_full_terms_click' ) ); | ||
}, [ dispatch ] ); | ||
|
||
return ( | ||
<div | ||
className={ clsx( 'a4a-migration-offer-v3', { 'is-expanded': isExpanded } ) } | ||
onClick={ onToggleView } | ||
role="button" | ||
tabIndex={ 0 } | ||
onKeyDown={ ( event ) => { | ||
if ( event.key === 'Enter' ) { | ||
onToggleView(); | ||
} | ||
} } | ||
> | ||
<div className="a4a-migration-offer-v3__main"> | ||
<h3 className="a4a-migration-offer-v3__title"> | ||
<span> | ||
{ translate( | ||
'{{b}}Limited time offer:{{/b}} Migrate your sites to Pressable or WordPress.com and earn up to $10,000!', | ||
{ | ||
components: { | ||
b: <b />, | ||
}, | ||
} | ||
) } | ||
</span> | ||
|
||
<Button className="a4a-migration-offer-v3__view-toggle-mobile" onClick={ onToggleView }> | ||
<Icon icon={ chevronDown } size={ 24 } /> | ||
</Button> | ||
</h3> | ||
|
||
{ isExpanded && ( | ||
<div className="a4a-migration-offer-v3__body"> | ||
<SimpleList | ||
items={ [ | ||
translate( | ||
"{{b}}WP Engine customers:{{/b}} You will receive $100 per site, up to $10,000. You will also get credited for the remaining time on your WP Engine contract, so you won't have to pay twice.", | ||
{ | ||
components: { | ||
b: <b />, | ||
}, | ||
} | ||
), | ||
translate( | ||
'{{b}}For any other host:{{/b}} You will receive $100 per site migrated up to a maximum of $3,000.', | ||
{ | ||
components: { | ||
b: <b />, | ||
}, | ||
} | ||
), | ||
] } | ||
/> | ||
|
||
<div className="a4a-migration-offer-v3__body-actions"> | ||
<Button | ||
variant="primary" | ||
href={ CONTACT_URL_FOR_MIGRATION_OFFER_HASH_FRAGMENT } | ||
onClick={ onContactUsClick } | ||
> | ||
{ translate( 'Contact us to learn more' ) } | ||
</Button> | ||
|
||
<Button | ||
variant="secondary" | ||
href={ A4A_MIGRATIONS_OVERVIEW_LINK } | ||
onClick={ onSeeFullTermClick } | ||
> | ||
{ translate( 'See full terms ↗' ) } | ||
</Button> | ||
|
||
<span className="a4a-migration-offer-v3__body-actions-footnote"> | ||
{ translate( '* Offer valid until the end of 2024' ) } | ||
</span> | ||
</div> | ||
</div> | ||
) } | ||
</div> | ||
|
||
<Button className="a4a-migration-offer-v3__view-toggle"> | ||
<Icon icon={ chevronDown } size={ 24 } /> | ||
</Button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MigrationOfferV3; |
111 changes: 111 additions & 0 deletions
111
client/a8c-for-agencies/components/a4a-migration-offer-v3/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
@import "@wordpress/base-styles/breakpoints"; | ||
@import "@wordpress/base-styles/mixins"; | ||
|
||
.a4a-migration-offer-v3 { | ||
display: flex; | ||
flex-direction: row; | ||
gap: 16px; | ||
|
||
border-radius: 4px; | ||
background-color: var(--color-surface); | ||
transition: padding 0.15s linear; | ||
padding: 8px 16px; | ||
cursor: pointer; | ||
|
||
@include break-medium { | ||
padding: 20px 32px; | ||
&.is-expanded { | ||
padding: 20px 32px 24px; | ||
} | ||
} | ||
} | ||
|
||
.theme-a8c-for-agencies .components-button.a4a-migration-offer-v3__view-toggle { | ||
display: none; | ||
|
||
@include break-medium { | ||
display: block; | ||
} | ||
} | ||
|
||
.a4a-migration-offer-v3__main { | ||
flex-direction: column; | ||
gap: 8px; | ||
flex-grow: 1; | ||
} | ||
|
||
.a4a-migration-offer-v3__title { | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
|
||
@include a4a-font-heading-md($font-weight: 400); | ||
|
||
@include break-medium { | ||
@include a4a-font-heading-lg($font-weight: 400); | ||
margin-block-start: 10px; | ||
margin-block-end: 8px; | ||
} | ||
} | ||
|
||
.a4a-migration-offer-v3__body { | ||
display: flex; | ||
gap: 24px; | ||
align-content: center; | ||
flex-direction: column; | ||
|
||
.simple-list { | ||
max-width: 800px; | ||
margin-block-start: 24px; | ||
margin-inline-start: 16px; | ||
} | ||
} | ||
|
||
.a4a-migration-offer-v3__body-actions { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 8px; | ||
|
||
@include break-xlarge { | ||
flex-direction: row; | ||
align-items: center; | ||
} | ||
} | ||
|
||
.a4a-migration-offer-v3__body-actions-footnote { | ||
@include a4a-font-body-sm; | ||
} | ||
|
||
.theme-a8c-for-agencies .components-button.a4a-migration-offer-v3__view-toggle-mobile { | ||
display: block; | ||
|
||
@include break-medium { | ||
display: none; | ||
} | ||
} | ||
|
||
.theme-a8c-for-agencies .components-button.a4a-migration-offer-v3__view-toggle, | ||
.theme-a8c-for-agencies .components-button.a4a-migration-offer-v3__view-toggle-mobile { | ||
&, | ||
&:hover, | ||
&:focus, | ||
&:focus-visible { | ||
background-color: transparent; | ||
|
||
&:not(:focus-visible) { | ||
border: none; | ||
box-shadow: none; | ||
} | ||
} | ||
|
||
svg { | ||
transition: transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275), color 0.2s ease-in; | ||
} | ||
} | ||
|
||
.a4a-migration-offer-v3.is-expanded { | ||
.components-button.a4a-migration-offer-v3__view-toggle svg, | ||
.components-button.a4a-migration-offer-v3__view-toggle-mobile svg { | ||
transform: rotate(180deg); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
client/a8c-for-agencies/sections/marketplace/hosting-overview-v3/hero-section/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { useBreakpoint } from '@automattic/viewport-react'; | ||
import clsx from 'clsx'; | ||
import { useTranslate } from 'i18n-calypso'; | ||
import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; | ||
import MigrationOfferV3 from 'calypso/a8c-for-agencies/components/a4a-migration-offer-v3'; | ||
import NavItem from 'calypso/components/section-nav/item'; | ||
import { SectionProps } from '..'; | ||
|
||
import './style.scss'; | ||
|
||
type Props = SectionProps & { | ||
onSectionChange: ( section: 'wpcom' | 'pressable' | 'vip' ) => void; | ||
isCompact?: boolean; | ||
}; | ||
|
||
export function HeroSection( | ||
{ section, onSectionChange, isCompact }: Props, | ||
ref: React.Ref< HTMLDivElement > | ||
) { | ||
const translate = useTranslate(); | ||
|
||
const isLargeScreen = useBreakpoint( '>1280px' ); | ||
|
||
const [ isMigrationOfferExpanded, setIsMigrationOfferExpanded ] = useState( false ); | ||
|
||
const onToggleMigrationOfferView = useCallback( () => { | ||
setIsMigrationOfferExpanded( ( isExpanded ) => ! isExpanded ); | ||
}, [] ); | ||
|
||
const featureTabs = useMemo( | ||
() => [ | ||
{ | ||
key: 'wpcom', | ||
label: isLargeScreen ? translate( 'Standard Agency Hosting' ) : translate( 'Standard' ), | ||
subtitle: isLargeScreen && translate( 'Optimized and hassle-free hosting' ), | ||
selected: section === 'wpcom', | ||
onClick: () => { | ||
onSectionChange( 'wpcom' ); | ||
}, | ||
}, | ||
{ | ||
key: 'pressable', | ||
label: isLargeScreen ? translate( 'Premier Agency Hosting' ) : translate( 'Premier' ), | ||
subtitle: isLargeScreen && translate( 'Best for large-scale businesses' ), | ||
selected: section === 'pressable', | ||
onClick: () => { | ||
onSectionChange( 'pressable' ); | ||
}, | ||
}, | ||
{ | ||
key: 'vip', | ||
label: translate( 'Enterprise' ), | ||
subtitle: isLargeScreen && translate( 'WordPress for enterprise-level demands' ), | ||
selected: section === 'vip', | ||
onClick: () => { | ||
onSectionChange( 'vip' ); | ||
}, | ||
}, | ||
], | ||
[ onSectionChange, isLargeScreen, section, translate ] | ||
); | ||
|
||
const navItems = featureTabs.map( ( featureTab ) => { | ||
return ( | ||
<NavItem | ||
className="hosting-v3-hero-section__tab" | ||
key={ featureTab.key } | ||
selected={ featureTab.selected } | ||
onClick={ featureTab.onClick } | ||
> | ||
{ featureTab.label && ( | ||
<div className="hosting-v3__nav-item-label">{ featureTab.label }</div> | ||
) } | ||
{ featureTab.subtitle && ( | ||
<div className="hosting-v3__nav-item-subtitle">{ featureTab.subtitle }</div> | ||
) } | ||
</NavItem> | ||
); | ||
} ); | ||
|
||
useEffect( () => { | ||
if ( isCompact ) { | ||
setIsMigrationOfferExpanded( false ); | ||
} | ||
}, [ isCompact ] ); | ||
|
||
return ( | ||
<div className={ clsx( 'hosting-v3-hero-section', { 'is-compact': isCompact } ) } ref={ ref }> | ||
<div className="hosting-v3-hero-section__content"> | ||
<div className="hosting-v3-hero-section__heading"> | ||
{ translate( | ||
'High Performance, Highly-Secure{{br/}}Managed WordPress Hosting for Agencies', | ||
{ | ||
components: { | ||
br: <br />, | ||
}, | ||
} | ||
) } | ||
</div> | ||
|
||
<MigrationOfferV3 | ||
isExpanded={ isMigrationOfferExpanded } | ||
onToggleView={ onToggleMigrationOfferView } | ||
/> | ||
</div> | ||
|
||
<ul className="hosting-v3-hero-section__tabs">{ navItems }</ul> | ||
</div> | ||
); | ||
} | ||
|
||
export default forwardRef( HeroSection ); |
Oops, something went wrong.