Skip to content

Commit 84397ce

Browse files
authored
Merge pull request #1692 from woocommerce/update/1610-integrate-ad-preview-with-api
Free Listings + Paid Ads: Use merchant's data to composite the ad previews
2 parents 6e68765 + 39668f8 commit 84397ce

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

js/src/components/paid-ads/campaign-preview/campaign-preview.js

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import { _x } from '@wordpress/i18n';
55
import { useState, useCallback, useEffect } from '@wordpress/element';
66
import { CSSTransition, TransitionGroup } from 'react-transition-group';
7+
import CurrencyFactory from '@woocommerce/currency';
8+
import { getSetting } from '@woocommerce/settings'; // eslint-disable-line import/no-unresolved
79

810
/**
911
* Internal dependencies
1012
*/
1113
import useCountdown from '.~/hooks/useCountdown';
14+
import useAppSelectDispatch from '.~/hooks/useAppSelectDispatch';
15+
import AppSpinner from '.~/components/app-spinner';
1216
import MockupShopping from './mockup-shopping';
1317
import MockupYouTube from './mockup-youtube';
1418
import MockupSearch from './mockup-search';
@@ -17,6 +21,7 @@ import MockupDisplay from './mockup-display';
1721
import MockupMap from './mockup-map';
1822
import productSampleImageURL from './images/product-sample-image.jpg';
1923
import shopSampleLogoURL from './images/shop-sample-logo.png';
24+
import { glaData } from '.~/constants';
2025
import './campaign-preview.scss';
2126

2227
/**
@@ -47,6 +52,13 @@ const fallbackProduct = {
4752
shopUrl: 'colleensteestore.com',
4853
};
4954

55+
const bestsellingQuery = {
56+
page: 1,
57+
per_page: 1,
58+
orderby: 'total_sales',
59+
order: 'desc',
60+
};
61+
5062
const mockups = [
5163
MockupShopping,
5264
MockupYouTube,
@@ -56,12 +68,36 @@ const mockups = [
5668
MockupGmail,
5769
];
5870

71+
function resolvePreviewProduct( products = [] ) {
72+
const currencyFactory = CurrencyFactory( getSetting( 'currency' ) );
73+
const [ product = {} ] = products;
74+
const { title, price, image_url: coverUrl } = product;
75+
const previewProduct = {
76+
title,
77+
coverUrl,
78+
price: currencyFactory.formatAmount( price ),
79+
shopName: getSetting( 'siteTitle' ),
80+
shopUrl: new URL( getSetting( 'homeUrl' ) ).host,
81+
shopLogoUrl: glaData.siteLogoUrl,
82+
};
83+
84+
Object.entries( previewProduct ).forEach( ( [ key, val ] ) => {
85+
// All possible values won't be number 0, so here simply use falsy condition to do fallback.
86+
if ( ! val ) {
87+
previewProduct[ key ] = fallbackProduct[ key ];
88+
}
89+
} );
90+
91+
return previewProduct;
92+
}
93+
5994
export default function CampaignPreview() {
6095
const [ index, setIndex ] = useState( 0 );
6196
const { second, callCount, startCountdown } = useCountdown();
62-
63-
// TODO: Fetch required data from API.
64-
const product = fallbackProduct;
97+
const { hasFinishedResolution, data } = useAppSelectDispatch(
98+
'getMCProductFeed',
99+
bestsellingQuery
100+
);
65101

66102
const moveBy = useCallback( ( step ) => {
67103
setIndex( ( currentIndex ) => {
@@ -70,15 +106,24 @@ export default function CampaignPreview() {
70106
}, [] );
71107

72108
useEffect( () => {
73-
if ( second === 0 ) {
109+
if ( hasFinishedResolution && second === 0 ) {
74110
if ( callCount > 0 ) {
75111
moveBy( 1 );
76112
}
77113
startCountdown( 5 );
78114
}
79-
}, [ second, callCount, startCountdown, moveBy ] );
115+
}, [ hasFinishedResolution, second, callCount, startCountdown, moveBy ] );
116+
117+
if ( ! hasFinishedResolution ) {
118+
return (
119+
<div className="gla-ads-mockup">
120+
<AppSpinner />
121+
</div>
122+
);
123+
}
80124

81125
const Mockup = mockups[ index ];
126+
const product = resolvePreviewProduct( data?.products );
82127

83128
return (
84129
<TransitionGroup className="gla-campaign-preview">

js/src/components/paid-ads/campaign-preview/campaign-preview.scss

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ $gla-campaign-preview-height: 270px;
4444
overflow: hidden;
4545
background-color: $white;
4646

47+
.app-spinner {
48+
align-items: center;
49+
height: 100%;
50+
}
51+
4752
// === Shared components within ad previews ===
4853
&__placeholder {
4954
height: 3px;
@@ -89,14 +94,15 @@ $gla-campaign-preview-height: 270px;
8994

9095
// Display smaller font sizes than browsers' limitations.
9196
&__scaled-text {
97+
height: 1em;
9298
transform: scale(0.5);
9399
transform-origin: top left;
94100
margin-right: -100%; // Inner shrinkage for offsetting the outer horizontal gap caused by 0.5 times scaling.
95101
margin-bottom: -0.5em; // Inner shrinkage for offsetting the outer vertical gap caused by 0.5 times scaling.
96102
white-space: nowrap;
97103
overflow: hidden;
98104
text-overflow: ellipsis;
99-
line-height: 1;
105+
line-height: 0.9; // With 1em height, it prevents the font descender from getting cropped out.
100106
font-size: 20px;
101107

102108
&--smaller {
@@ -120,6 +126,10 @@ $gla-campaign-preview-height: 270px;
120126
}
121127

122128
&--ad-badge {
129+
// Reset height and line-height because ad badge holds enough height for font descender.
130+
height: auto;
131+
line-height: 1;
132+
123133
// The same vertical inner shrinkage as above.
124134
// A: Height of badge = &--ad-badge font-size + vertical padding
125135
// B: Height of text after badge = &--smaller font-size

0 commit comments

Comments
 (0)