Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert "Add sites migration banner"" #95402

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions client/hosting/sites/components/dotcom-style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@
}
}

.sites-a8c-for-agencies-banner-container {
.sites-banner-container {
display: flex;
justify-content: center;
}

.sites-a8c-for-agencies-banner {
.sites-banner {
width: 100%;
margin-inline: 16px;

.banner__action {
Expand Down Expand Up @@ -634,7 +635,7 @@
}
}

.sites-a8c-for-agencies-banner-container {
.sites-banner-container {
display: none;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Gridicon } from '@automattic/components';
import { HelpCenter } from '@automattic/data-stores';
import { localizeUrl } from '@automattic/i18n-utils';
import { useDispatch as useDataStoreDispatch } from '@wordpress/data';
import { translate } from 'i18n-calypso';
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { isCardDismissed } from 'calypso/blocks/dismissible-card/selectors';
import Banner from 'calypso/components/banner';
import type { Status } from '@automattic/sites/src/use-sites-list-grouping';

const HELP_CENTER_STORE = HelpCenter.register();

type SitesDashboardBannersManagerProps = {
sitesStatuses: Status[];
sitesCount: number;
};

const SitesDashboardBannersManager = ( {
sitesStatuses,
sitesCount,
}: SitesDashboardBannersManagerProps ) => {
const { setShowHelpCenter } = useDataStoreDispatch( HELP_CENTER_STORE );

const showA8CForAgenciesBanner = sitesCount >= 5;
const migrationPendingSitesCount = sitesStatuses.find(
( status ) => status.name === 'migration-pending'
)?.count;

const isMigrationBannerDismissed = useSelector( isCardDismissed( 'migration-pending-sites' ) );

const openHelpCenter = useCallback( () => {
setShowHelpCenter( true );
}, [ setShowHelpCenter ] );

if (
migrationPendingSitesCount &&
migrationPendingSitesCount > 0 &&
// If the banner is dismissed, we don't want to return earlier to show the other banner.
! isMigrationBannerDismissed
) {
return (
<div className="sites-banner-container">
<Banner
icon="info-outline"
callToAction={ translate( 'Get help' ) }
primaryButton={ false }
className="sites-banner"
description={ translate(
"Let's solve it together. Reach out to our support team to get your migration started."
) }
dismissPreferenceName="migration-pending-sites"
event="get-help"
horizontal
onClick={ openHelpCenter }
target="_blank"
title={ translate( 'Stuck on your migration?' ) }
tracksClickName="calypso_sites_dashboard_migration_banner_click"
/>
</div>
);
}

if ( showA8CForAgenciesBanner ) {
return (
<div className="sites-banner-container">
<Banner
callToAction={ translate( 'Learn more {{icon/}}', {
components: {
icon: <Gridicon icon="external" />,
},
} ) }
className="sites-banner"
description={ translate(
"Earn up to 50% revenue share and get volume discounts on WordPress.com hosting when you migrate sites to our platform and promote Automattic's products to clients."
) }
dismissPreferenceName="dismissible-card-a8c-for-agencies-sites"
event="learn-more"
horizontal
href={ localizeUrl( 'https://wordpress.com/for-agencies?ref=wpcom-sites-dashboard' ) }
target="_blank"
title={ translate( "Building sites for customers? Here's how to earn more." ) }
tracksClickName="calypso_sites_dashboard_a4a_banner_click"
/>
</div>
);
}

return null;
};

export default SitesDashboardBannersManager;
51 changes: 7 additions & 44 deletions client/hosting/sites/components/sites-dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Gridicon } from '@automattic/components';
import { localizeUrl, useHasEnTranslation } from '@automattic/i18n-utils';
import {
type SiteExcerptData,
SitesSortKey,
Expand Down Expand Up @@ -28,7 +26,6 @@ import LayoutHeader, {
} from 'calypso/a8c-for-agencies/components/layout/header';
import LayoutTop from 'calypso/a8c-for-agencies/components/layout/top';
import { GuidedTourContextProvider } from 'calypso/a8c-for-agencies/data/guided-tours/guided-tour-context';
import Banner from 'calypso/components/banner';
import DocumentHead from 'calypso/components/data/document-head';
import { useSiteExcerptsQuery } from 'calypso/data/sites/use-site-excerpts-query';
import { isP2Theme } from 'calypso/lib/site/utils';
Expand All @@ -49,6 +46,7 @@ import {
} from '../onboarding-tours';
import { DOTCOM_OVERVIEW, FEATURE_TO_ROUTE_MAP } from './site-preview-pane/constants';
import DotcomPreviewPane from './site-preview-pane/dotcom-preview-pane';
import SitesDashboardBannersManager from './sites-dashboard-banners-manager';
import SitesDashboardHeader from './sites-dashboard-header';
import DotcomSitesDataViews, { useSiteStatusGroups } from './sites-dataviews';
import { getSitesPagination } from './sites-dataviews/utils';
Expand Down Expand Up @@ -131,8 +129,6 @@ const SitesDashboard = ( {
[ 'theme_slug' ]
);

const hasEnTranslation = useHasEnTranslation();

useShowSiteCreationNotice( allSites, newSiteID );
useShowSiteTransferredNotice();

Expand Down Expand Up @@ -272,7 +268,7 @@ const SitesDashboard = ( {
}, [ dataViewsState.filters, siteStatusGroups ] );

// Filter sites list by status group.
const { currentStatusGroup } = useSitesListGrouping( allSites, {
const { currentStatusGroup, statuses } = useSitesListGrouping( allSites, {
status: statusSlug || 'all',
showHidden: true,
} );
Expand Down Expand Up @@ -354,8 +350,6 @@ const SitesDashboard = ( {
const hideListing = false;
const isNarrowView = false;

const showA8CForAgenciesBanner = paginatedSites.length >= 5;

const dashboardTitle = siteType === 'p2' ? translate( 'P2s' ) : translate( 'Sites' );

return (
Expand Down Expand Up @@ -383,42 +377,11 @@ const SitesDashboard = ( {
</LayoutTop>

<DocumentHead title={ dashboardTitle } />
{ showA8CForAgenciesBanner && (
<div className="sites-a8c-for-agencies-banner-container">
<Banner
callToAction={ translate( 'Learn more {{icon/}}', {
components: {
icon: <Gridicon icon="external" />,
},
} ) }
className="sites-a8c-for-agencies-banner"
description={
hasEnTranslation(
"Earn up to 50% revenue share and get volume discounts on WordPress.com hosting when you migrate sites to our platform and promote Automattic's products to clients."
)
? translate(
"Earn up to 50% revenue share and get volume discounts on WordPress.com hosting when you migrate sites to our platform and promote Automattic's products to clients."
)
: translate(
'Manage multiple WordPress sites from one place, get volume discounts on hosting products, and earn up to 50% revenue share when you migrate sites to our platform and refer our products to clients.'
)
}
dismissPreferenceName="dismissible-card-a8c-for-agencies-sites"
event="learn-more"
horizontal
href={ localizeUrl(
'https://wordpress.com/for-agencies?ref=wpcom-sites-dashboard'
) }
target="_blank"
title={
hasEnTranslation( "Building sites for customers? Here's how to earn more." )
? translate( "Building sites for customers? Here's how to earn more." )
: translate( 'Managing multiple sites? Meet our agency hosting' )
}
tracksClickName="calypso_sites_dashboard_a4a_banner_click"
/>
</div>
) }
<SitesDashboardBannersManager
sitesStatuses={ statuses }
sitesCount={ paginatedSites.length }
/>

<DotcomSitesDataViews
sites={ paginatedSites }
isLoading={ isLoading || ! initialSortApplied }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import Banner from 'calypso/components/banner';
import SitesDashboardBannersManager from '../sites-dashboard-banners-manager';
import type { Status } from '@automattic/sites/src/use-sites-list-grouping';

// Mock the Banner component
jest.mock( 'calypso/components/banner', () => {
return jest.fn( ( { title } ) => <div>{ title }</div> );
} );

const mockStore = configureStore();

describe( 'SitesDashboardBannersManager', () => {
let store;

beforeEach( () => {
store = mockStore( {
preferences: {
localValues: {
'dismissible-card-migration-pending-sites': false,
},
},
} );
} );

it( 'renders migration banner when migration pending sites is greater than 0', () => {
const sitesStatuses = [ { name: 'migration-pending', count: 1 } as Status ];

const { getByText } = render(
<Provider store={ store }>
<SitesDashboardBannersManager sitesStatuses={ sitesStatuses } sitesCount={ 1 } />
</Provider>
);

expect( getByText( 'Stuck on your migration?' ) ).toBeInTheDocument();
} );

it( 'does not render migration banner if it is dismissed', () => {
store = mockStore( {
preferences: {
localValues: {
'dismissible-card-migration-pending-sites': true,
},
},
} );

const sitesStatuses = [ { name: 'migration-pending', count: 1 } as Status ];

const { queryByText } = render(
<Provider store={ store }>
<SitesDashboardBannersManager sitesStatuses={ sitesStatuses } sitesCount={ 1 } />
</Provider>
);

expect( queryByText( 'Stuck on your migration?' ) ).not.toBeInTheDocument();
} );

it( 'renders A8C for Agencies banner when sitesCount is 5 or more', () => {
const sitesStatuses = [];

const { getByText } = render(
<Provider store={ store }>
<SitesDashboardBannersManager sitesStatuses={ sitesStatuses } sitesCount={ 5 } />
</Provider>
);

expect(
getByText( "Building sites for customers? Here's how to earn more." )
).toBeInTheDocument();
expect( Banner ).toHaveBeenCalled();
} );

it( 'does not render A8C for Agencies banner when sitesCount is less than 5', () => {
const sitesStatuses = [];

const { queryByText } = render(
<Provider store={ store }>
<SitesDashboardBannersManager sitesStatuses={ sitesStatuses } sitesCount={ 4 } />
</Provider>
);

expect(
queryByText( "Building sites for customers? Here's how to earn more." )
).not.toBeInTheDocument();
} );
} );
Loading