Skip to content

Commit 0445560

Browse files
Merge pull request #23 from neilmistryamplience/feat/stylitics-release
feat: Stylitics integration
2 parents d5edd0c + fa46421 commit 0445560

24 files changed

+238
-10
lines changed

Diff for: README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ The package also includes a Debug/X-Ray panel to help understand how the pages a
88

99
`dc-demostore-core` is intended for DEMO PURPOSES ONLY, and *not* for production-optimized environments.
1010

11-
1211
# Table of Contents
1312
- [Getting Started](#getting-started)
1413
- [Storybook](#storybook)
@@ -82,6 +81,11 @@ At a high level the basic steps are:
8281
3. Configure & use `dc-demostore-cli` to populate content
8382
4. Point `dc-demostore-core` to your Dynamic Content Hub and run
8483

84+
> Note: If you already have an Amplience Demostore account and are upgrading to verson `1.4.0` or later, you should upload the rendering templates for Stylitics components into your Content Hub.
85+
86+
Location: `examples/crs`
87+
Upload asset store in Content Hub: `Templates`
88+
8589
## Requesting an Amplience Demo Store Environment
8690

8791
This application is setup to run with a predefined Amplience account structure to have all of the capabilities and organisational requirements to showcase capabilities effectively.

Diff for: components/cms-layout/CmsComponent/CmsComponent.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import ProductAttribute from '@components/product/ProductAttribute';
44
import ProductColor from '@components/product/ProductColor';
55
import ProductHero from '@components/product/ProductHero';
66
import ProductMediaViewer from '@components/product/ProductMediaViewer';
7+
import Generic from '@components/stylitics/Generic/Generic';
78
import ProductRichText from '@components/product/ProductRichText';
89
import ProductSize from '@components/product/ProductSize';
910
import Accordion from '@components/ui/Accordion/Accordion';
@@ -49,6 +50,7 @@ const mapping: any = {
4950
return <Grid {...remappedProps} />;
5051
},
5152
'product_image_viewer': ProductMediaViewer,
53+
'stylitics': Generic,
5254
'product_attribute': ProductAttribute,
5355
'product_atb': AddToBasket,
5456
'product_size': ProductSize,

Diff for: components/cms-modern/ContentBlock/ContentBlock.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import ThemeWrapper from '@components/cms-modern/ThemeWrapper';
3737
import Video from '@components/cms-modern/Video';
3838

3939
import { useRouter } from 'next/router';
40+
import Generic from '@components/stylitics/Generic/Generic';
41+
4042

4143
export type ContentBlockType = 'SLOT' | 'CONTENT';
4244

@@ -79,7 +81,13 @@ const ComponentMapping: any = {
7981
'https://demostore.amplience.com/slots/flexible' : FlexibleSlot,
8082
'https://demostore.amplience.com/slots/landing-page' : BannerSlot,
8183
'https://demostore.amplience.com/slots/localized-banner' : LocalizedBannerSlot,
82-
'https://demostore.amplience.com/slots/personalized-banner' : PersonalizedBannerSlot
84+
'https://demostore.amplience.com/slots/personalized-banner' : PersonalizedBannerSlot,
85+
'https://demostore.amplience.com/content/stylitics/generic' : Generic,
86+
'https://demostore.amplience.com/content/stylitics/hotspots' : Generic,
87+
'https://demostore.amplience.com/content/stylitics/moodboard' : Generic,
88+
'https://demostore.amplience.com/content/stylitics/gallery' : Generic,
89+
'https://demostore.amplience.com/content/stylitics/classic' : Generic,
90+
'https://demostore.amplience.com/content/stylitics/main-and-detail' : Generic,
8391

8492
};
8593

Diff for: components/cms/CuratedProductGrid/CuratedProductGridCard/CuratedProductGridCard.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const CuratedProductGridCard: React.SFC<Props> = (props) => {
8585
let imageUrl = result.overrides?.image
8686
? `https://${result.overrides.image?.defaultHost}/i/${result.overrides.image?.endpoint}/${result.overrides.image?.name}`
8787
: `${result.variants[0].images[0].url}`;
88-
imageUrl += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40'
88+
imageUrl += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40&w=540&h=812'
8989

9090
return (
9191
<Link href={`/product/${result.id}/${result.slug}`}>

Diff for: components/product/ProductCard/ProductCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ const ProductCardSkeleton: React.SFC<Props> = (props) => {
9393

9494
firstImage = variant.images[0].url.replace("i8.amplience.net", "cdn.media.amplience.net");
9595
if(firstImage.indexOf('cdn.media.amplience.net') > 0){
96-
firstImage += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40&w=540&upscale=false'
96+
firstImage += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40&w=540&h=812'
9797
}
9898
}
9999
if (variant.images[1] && variant.images[1].url){
100100
secondImage = variant.images[1].url.replace("i8.amplience.net", "cdn.media.amplience.net");
101101
if(secondImage.indexOf('cdn.media.amplience.net') > 0){
102-
secondImage += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40&w=540&upscale=false'
102+
secondImage += '?fmt=auto&qlt=default&fmt.jpeg.qlt=75&fmt.webp.qlt=60&fmt.jp2.qlt=40&w=540&h=812'
103103
}
104104
}
105105
}

Diff for: components/stylitics/Generic/Generic.tsx

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import React, { createRef, useEffect } from 'react';
2+
import { Theme, Typography } from '@mui/material';
3+
import { useProduct } from '../../product/WithProduct/WithProduct';
4+
import _ from 'lodash'
5+
import { withStyles, WithStyles } from '@mui/styles'
6+
import { fromContentItem, createWidget, StyliticsWidget } from '@amplience/dc-integration-stylitics';
7+
import { useRouter } from 'next/router';
8+
9+
const styles = (theme: Theme) => ({
10+
});
11+
12+
/**
13+
* Generic props
14+
*/
15+
interface Props extends WithStyles<typeof styles> {
16+
className?: string;
17+
style?: React.CSSProperties;
18+
header?: string;
19+
gallery?: any;
20+
moodboard?: any;
21+
mainAndDetail?: any;
22+
hotspots?: any;
23+
classic?: any;
24+
api?: any;
25+
display?: any;
26+
price?: any;
27+
account?: string;
28+
sku?: string;
29+
view?:string;
30+
variant?:string;
31+
min: number;
32+
max: number;
33+
}
34+
35+
/**
36+
* Generic Component that can handle all the different Stylitics views
37+
* @param props
38+
* @returns
39+
*/
40+
const Generic: React.FunctionComponent<Props> = (props) => {
41+
const {
42+
header,
43+
} = props;
44+
45+
const {
46+
product
47+
} = useProduct() || {};
48+
49+
const container = createRef<HTMLDivElement>();
50+
51+
const {
52+
push
53+
} = useRouter();
54+
55+
useEffect(() => {
56+
if (!window || !container.current) {
57+
return;
58+
}
59+
60+
let target = container.current;
61+
let active = true;
62+
let widgetInstance: StyliticsWidget;
63+
64+
const item = {
65+
...props,
66+
account: product?.categories[0]?.parent?.id || props.account || 'demo-womens',
67+
sku: product ? product.id : props.sku
68+
}
69+
70+
const args = fromContentItem(item as any);
71+
72+
const handleApply = async (props: any) => {
73+
await push(`/product/${props.item.remote_id}/${_.kebabCase(props.item.name)}`)
74+
}
75+
76+
createWidget(target, args).then((widget: StyliticsWidget) => {
77+
if (active) {
78+
widgetInstance = widget;
79+
80+
// Click override to redirect to Product page
81+
widget.override("click", "item", function (props: any) {
82+
handleApply(props as any)
83+
})
84+
85+
widget.start();
86+
} else {
87+
widget.destroy();
88+
}
89+
})
90+
91+
// Cleanup
92+
return () => {
93+
if (widgetInstance) {
94+
widgetInstance.destroy();
95+
}
96+
97+
if (target) {
98+
target.innerHTML = '';
99+
}
100+
101+
active = false;
102+
};
103+
}, [container, props, product]);
104+
105+
return (
106+
<div>
107+
{
108+
header && (
109+
<Typography variant="h2" component="h2">
110+
{header}
111+
</Typography>
112+
)
113+
}
114+
<div ref={container} className="stylitics"></div>
115+
</div>
116+
);
117+
};
118+
119+
export default withStyles(styles)(Generic);

Diff for: components/stylitics/Generic/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Generic';

Diff for: docs/Components.md

+6
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,11 @@
3434
| text | Text | Markdown text |
3535
| themeWrapper | ThemeWrapper | Wrapper to change theme for any component |
3636
| video | Video | Video element |
37+
| stylitics/generic | stylitics/Generic | ![Stylitics Generic](../media/component-stylitics-generic.png) Can render all stylitics widgets from a single content type with all available options |
38+
| stylitics/hotspots | stylitics/Generic | ![Stylitics Hotspots](../media/component-stylitics-hotspots.png) Only options for a Stylitics Hotspot Widget |
39+
| stylitics/moodboard | stylitics/Generic | ![Stylitics Moodboard](../media/component-stylitics-moodboard.png) Only options for a Stylitics Moodboard Widget |
40+
| stylitics/gallery | stylitics/Generic | ![Stylitics Gallery](../media/component-stylitics-gallery.png) Only options for a Stylitics Gallery Widget |
41+
| stylitics/classic | stylitics/Generic | ![Stylitics Classic](../media/component-stylitics-classic.png) Only options for a Stylitics Classic Widget |
42+
| stylitics/main-and-detail | stylitics/Generic | ![Stylitics Main & Detail](../media/component-stylitics-main-and-detail.png) Only options for a Stylitics Main & Detail Widget |
3743

3844
[back](../README.md)

Diff for: docs/DeepDive.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [Theming](#theming)
88
- [Admin UI Panels](#admin-ui-panels)
99
- [Shoppable Image](#shoppable-image)
10+
- [Stylitics](#stylitics)
1011

1112
## Fetching content
1213

@@ -455,4 +456,15 @@ There are several options that you can put in the selector column that drive spe
455456
| The ID of the product<br/>`123456789` | `.product` |
456457
| The slug of the category<br/>`women-bags` | `.category` |
457458

458-
[top](#table-of-content)
459+
460+
## Stylitics
461+
462+
Uses the [Amplience Stylitics Integration (See link for full documentation)](https://github.com/amplience/dc-integration-stylitics) to render Stylitics widgets as a component. Stylitics and Amplience are a great fit for our creating automated shoppable experience using the great capabilities of Stylitics to increase AOV and basket size.
463+
464+
The demostore implementation includes the following:
465+
* Sample product set that can be used when selecting products (see [documentation](https://github.com/amplience/dc-integration-middleware/blob/main/docs/vendor/commerce/rest.md))
466+
* All of the component and implementation in React/NextJS
467+
* Sample implementation for overriding link values
468+
* Sample implementation of inheriting SKU from PDP
469+
470+
[top](#table-of-content)

Diff for: docs/FeatureHiLites.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
- GraphQL implentation to connect to e-Commerce (CommerceTools, BigCommerce, file based catalog, etc.)
1010
- Admin Panel (visualise content, slots, editons, switch between production and staging view)
1111
- Custom Dashboards (translation & production Kanban board, deep clone)
12+
- [Stylitics](https://stylitics.com) components for configuration in content not code
1213

1314
[back](../README.md)

Diff for: examples/crs/stylitics-crs-card.html

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<html>
2+
<head>
3+
<meta charset="utf-8">
4+
<title>Stylitics Card Renderer</title>
5+
<style>
6+
.rootContainer {
7+
transform-origin: top left;
8+
transform: scale(0.5);
9+
width: 200%;
10+
height: 200%;
11+
background-color: #FFFFFF;
12+
}
13+
</style>
14+
<!-- Import the Amplience Stylitics Helper scripts -->
15+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/dist/ampStylitics.browser.umd.min.js"></script>
16+
</head>
17+
<body>
18+
<div class="rootContainer">
19+
{{> stylitics-templateChooser this}}
20+
</div>
21+
</body>
22+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/examples/stylitics-widget.js"></script>
23+
</html>

Diff for: examples/crs/stylitics-crs-visualisation.html

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<html>
2+
<head>
3+
<meta charset="utf-8">
4+
<title>Stylitics Visualisation Renderer</title>
5+
<!-- Import the Amplience Visualization SDK -->
6+
<script src="https://unpkg.com/dc-visualization-sdk/dist/lib/dc-visualization-sdk.umd.js"></script>
7+
<!-- Import the Amplience Stylitics Helper scripts -->
8+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/dist/ampStylitics.browser.umd.min.js"></script>
9+
</head>
10+
<body>
11+
<div>
12+
{{> stylitics-templateChooser this}}
13+
</div>
14+
</body>
15+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/examples/stylitics-widget.js"></script>
16+
</html>

Diff for: examples/crs/stylitics-generic-renderer.html

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<div class="amp-stylitics-container" data-amp-stylitics-data="{{{escape (stringify this)}}}" >
2+
</div>

Diff for: examples/crs/stylitics-templateChooser.html

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/generic")) ~}} {{> stylitics-generic-renderer }} {{~/if}}
2+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/hotspots")) ~}} {{> stylitics-generic-renderer }} {{~/if}}
3+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/moodboard")) ~}} {{> stylitics-generic-renderer }} {{~/if}}
4+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/gallery")) ~}} {{> stylitics-generic-renderer }} {{~/if}}
5+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/classic")) ~}} {{> stylitics-generic-renderer }} {{~/if}}
6+
{{#if (test this.[@type] (toRegex "https://demostore.amplience.com/content/stylitics/main-and-detail")) ~}} {{> stylitics-generic-renderer }} {{~/if}}

Diff for: examples/stylitics-generic-html.html

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<html>
2+
<head>
3+
<!-- Import the Amplience Delivery SDK -->
4+
<script src="https://unpkg.com/dc-delivery-sdk-js/dist/dynamicContent.browser.umd.min.js"></script>
5+
<!-- Import the Amplience Visualization SDK -->
6+
<script src="https://unpkg.com/dc-visualization-sdk/dist/lib/dc-visualization-sdk.umd.js"></script>
7+
<!-- Import the Amplience Stylitics Helper scripts -->
8+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/dist/ampStylitics.browser.umd.min.js"></script>
9+
</head>
10+
<body>
11+
<!-- Add a DIV with a container -->
12+
<div class="amp-stylitics-container" id="vis-target"></div>
13+
<script>
14+
const elem = document.getElementById('vis-target');
15+
16+
const queryString = window.location.search;
17+
const urlParams = new URLSearchParams(queryString);
18+
elem.setAttribute('data-widget-id', urlParams.get('content'))
19+
</script>
20+
<script src="https://unpkg.com/@amplience/dc-integration-stylitics/examples/stylitics-widget.js"></script>
21+
</body>
22+
</html>

Diff for: media/component-stylitics-classic.png

1.79 MB
Loading

Diff for: media/component-stylitics-gallery.png

1.11 MB
Loading

Diff for: media/component-stylitics-generic.png

414 KB
Loading

Diff for: media/component-stylitics-hotspots.png

1.57 MB
Loading

Diff for: media/component-stylitics-main-and-detail.png

735 KB
Loading

Diff for: media/component-stylitics-moodboard.png

1.21 MB
Loading

Diff for: package-lock.json

+8-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@amplience/dc-demostore-core",
3-
"version": "1.3.0",
3+
"version": "1.4.0",
44
"private": false,
55
"scripts": {
66
"dev": "next dev",
@@ -12,6 +12,7 @@
1212
},
1313
"dependencies": {
1414
"@amplience/dc-demostore-integration": "git+https://github.com/amplience/dc-demostore-integration.git#v1.1.3",
15+
"@amplience/dc-integration-stylitics": "^1.0.0",
1516
"@emotion/core": "^11.0.0",
1617
"@emotion/react": "^11.7.1",
1718
"@emotion/styled": "^11.6.0",
@@ -106,4 +107,3 @@
106107
},
107108
"homepage": "https://github.com/amplience/dc-demostore-core#readme"
108109
}
109-

Diff for: public/images/amplience.png

-26.5 KB
Loading

0 commit comments

Comments
 (0)