Skip to content

Commit d559ec0

Browse files
committed
polish pdp
1 parent 2c894c6 commit d559ec0

9 files changed

Lines changed: 164 additions & 29 deletions

File tree

gulpfile.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const fs = require('fs-extra');
33
const path = require('path');
44
const gulp = require('gulp');
5+
const addsrc = require('gulp-add-src');
56
const postcss = require('gulp-postcss');
67
const sourcemaps = require('gulp-sourcemaps');
78
const concat = require('gulp-concat');
@@ -15,8 +16,7 @@ function saveTokens(cssFile, exportTokens) {
1516
}
1617

1718
const src = [
18-
'src/**/*.css',
19-
'node_modules/react-image-gallery/styles/css/image-gallery.css',
19+
'src/components/**/*.css',
2020
];
2121

2222
gulp.task('css', function () {
@@ -29,6 +29,10 @@ gulp.task('css', function () {
2929
processTokens: saveTokens,
3030
})
3131
]) )
32+
.pipe(addsrc.prepend([
33+
'src/css/reset.css',
34+
'node_modules/react-image-gallery/styles/css/image-gallery.css'
35+
]))
3236
.pipe( concat('bundle.css') )
3337
.pipe( gulp.dest('lib/') );
3438
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"flow-bin": "^0.46.0",
5454
"fs-extra": "^3.0.1",
5555
"gulp": "^3.9.1",
56+
"gulp-add-src": "^0.2.0",
5657
"gulp-concat": "^2.6.1",
5758
"gulp-postcss": "^7.0.0",
5859
"gulp-sourcemaps": "^2.6.0",

src/components/pdp/pdp.jsx

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type State = {
5050

5151
export default class Pdp extends Component<DefaultProps, Props, State> {
5252
_productVariants: ProductVariants;
53+
_productViewTracked: boolean = false;
5354

5455
state: State = {
5556
currentSku: null,
@@ -60,6 +61,14 @@ export default class Pdp extends Component<DefaultProps, Props, State> {
6061
t: _.identity,
6162
};
6263

64+
componentDidMount() {
65+
this.trackProductView();
66+
}
67+
68+
componentWillReceiveProps(nextProps: Props) {
69+
this.trackProductView(nextProps);
70+
}
71+
6372
get isArchived(): boolean {
6473
return !!_.get(this.props, ['product', 'archivedAt']);
6574
}
@@ -68,13 +77,33 @@ export default class Pdp extends Component<DefaultProps, Props, State> {
6877
return this.state.currentSku || this.sortedSkus[0];
6978
}
7079

71-
get sortedSkus(): Array<Sku> {
80+
getSortedSkus(props: Props = this.props): Array<Sku> {
7281
return _.sortBy(
73-
_.get(this.props, 'product.skus', []),
82+
_.get(props, 'product.skus', []),
7483
'attributes.salePrice.v.value'
7584
);
7685
}
7786

87+
get sortedSkus(): Array<Sku> {
88+
return this.getSortedSkus();
89+
}
90+
91+
trackProductView(props: Props = this.props) {
92+
if (this._productViewTracked) return;
93+
94+
const {
95+
isLoading,
96+
notFound,
97+
fetchError,
98+
product
99+
} = props;
100+
101+
if (!isLoading && !notFound && !fetchError && product) {
102+
tracking.viewDetails(this.getProductView(props));
103+
this._productViewTracked = true;
104+
}
105+
}
106+
78107
@autobind
79108
setCurrentSku(currentSku: Sku) {
80109
this.setState({ currentSku });
@@ -87,12 +116,12 @@ export default class Pdp extends Component<DefaultProps, Props, State> {
87116
this.setState(assoc(this.state, namePath, stateValue));
88117
}
89118

90-
get productView(): TProductView {
91-
const attributes = _.get(this.props.product, 'attributes', {});
119+
getProductView(props: Props = this.props): TProductView {
120+
const attributes = _.get(props.product, 'attributes', {});
92121
const price = _.get(this.currentSku, 'attributes.salePrice.v', {});
93122
let images = _.get(this.currentSku, ['albums', '0', 'images'], []);
94123
if (_.isEmpty(images)) {
95-
images = _.get(this.props.product, ['albums', '0', 'images'], []);
124+
images = _.get(props.product, ['albums', '0', 'images'], []);
96125
}
97126
const imageUrls = images.map(image => image.src);
98127

@@ -102,10 +131,14 @@ export default class Pdp extends Component<DefaultProps, Props, State> {
102131
images: imageUrls,
103132
currency: _.get(price, 'currency', 'USD'),
104133
price: _.get(price, 'value', 0),
105-
skus: this.sortedSkus,
134+
skus: this.getSortedSkus(props),
106135
};
107136
}
108137

138+
get productView(): TProductView {
139+
return this.getProductView();
140+
}
141+
109142
get productShortDescription(): ?Element<any> {
110143
const shortDescription = _.get(this.props.product, 'attributes.shortDescription.v');
111144

src/components/related-products-list/related-products-list.jsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ import styles from './related-products-list.css';
1111
import WaitAnimation from 'components/core/wait-animation/wait-animation';
1212
import ListItem from './related-list-item';
1313

14+
// types
15+
import type { Product } from '@foxcomm/api-js/types/api/views/product';
16+
1417
type Props = {
15-
list: ?Array<Object>,
16-
productsOrder: ?Array<number>,
18+
list: ?Array<Product>,
19+
productsOrder?: Array<number>,
1720
isLoading: ?boolean,
1821
title: string,
1922
};
@@ -34,30 +37,25 @@ class RelatedProductsList extends Component {
3437
title: 'You Might Also Like',
3538
};
3639

37-
renderProducts() {
40+
renderProducts(): ?Array<Element<ListItem>> {
3841
const { list, productsOrder } = this.props;
3942

40-
if (_.isEmpty(list)) return null;
41-
42-
let sortedProductsList = [];
43-
_.forEach(productsOrder, function(productId) {
44-
sortedProductsList = _.concat(sortedProductsList, _.find(list, { productId }));
45-
});
43+
if (list == null || list.length == 0) return null;
4644

47-
const avoidKeyCollision = 9999;
45+
let sortedProductsList: Array<Product> = list;
4846

47+
if (productsOrder) {
48+
sortedProductsList = _.map(productsOrder, productId => _.find(list, {productId}));
49+
}
4950
const { startingId } = this.state;
50-
const endingId = Math.min(sortedProductsList.length, startingId + 6);
51-
52-
const toDisplay = _.slice(sortedProductsList, startingId, endingId);
51+
const toDisplay = sortedProductsList.slice(startingId, startingId + 6);
5352

5453
return _.map(toDisplay, (item, index) => {
5554
return (
5655
<ListItem
5756
{...item}
5857
index={index}
59-
key={`product-${_.get(item, 'id', _.random(avoidKeyCollision))}`}
60-
ref={`product-${_.get(item, 'id', _.random(avoidKeyCollision))}`}
58+
key={`product-${_.get(item, 'id', index)}`}
6159
/>
6260
);
6361
});

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ export WrapToLines from './components/core/wrap-to-lines/wrap-to-lines';
3232
export Pdp from './components/pdp/pdp';
3333
export ProductImage from './components/product-image/product-image';
3434
export ImagePlaceholder from './components/product-image/image-placeholder';
35+
export RelatedProductList from './components/related-products-list/related-products-list';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script type="text/javascript">
5+
function initGA(gaId, enableLocal) {
6+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
7+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
8+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
9+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
10+
11+
var gaOpts = enableLocal ? { cookieDomain: 'none' } : 'auto';
12+
ga('create', gaId, gaOpts);
13+
ga('send', 'pageview');
14+
}
15+
var enableAnalyticsWhileLocalDevelopment = false;
16+
initGA('GA-XXXXXXXX-X', enableAnalyticsWhileLocalDevelopment);
17+
</script>
18+
</head>
19+
<body>
20+
</body>
21+
</html>

src/lib/analytics.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
import _ from 'lodash';
33
import { isGiftCard } from 'paragons/sku';
44

5+
function ga(...args) {
6+
if (typeof window != 'undefined' && window.ga) {
7+
window.ga(...args);
8+
}
9+
}
10+
511
export function trackPageView(page, fieldsObject) {
612
ga('send', 'pageview', page, fieldsObject);
713
}

src/opt/css-modules-export.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
2626
const loader = getLoader(opts, plugins);
2727
const parser = new Parser(loader.fetch.bind(loader));
2828

29-
return postcss([...plugins, parser.plugin])
29+
return postcss([parser.plugin])
3030
.process(css, { from: inputFile })
3131
.then(() => {
3232
const out = loader.finalSource;

0 commit comments

Comments
 (0)