@nosto/nosto-react 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,34 @@
1
+ import React, { useEffect } from "react";
2
+ import { useNostoContext } from "../Provider/context.client";
3
+
4
+ const NostoFohofo: React.FC = () => {
5
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
6
+ useEffect(() => {
7
+ // @ts-ignore
8
+ if (clientScriptLoaded) {
9
+ window.nostojs((api: any) => {
10
+ api
11
+ .defaultSession()
12
+ .setVariation(currentVariation)
13
+ .setResponseMode("HTML")
14
+ .viewNotFound()
15
+ .setPlacements(api.placements.getPlacements())
16
+ .load()
17
+ .then((data: object) => {
18
+ // @ts-ignore
19
+ api.placements.injectCampaigns(data.recommendations);
20
+ });
21
+ });
22
+ }
23
+ }, [clientScriptLoaded, currentVariation]);
24
+
25
+ return (
26
+ <>
27
+ <div className="nosto_page_type" style={{ display: "none" }}>
28
+ notfound
29
+ </div>
30
+ </>
31
+ );
32
+ };
33
+
34
+ export default NostoFohofo;
@@ -0,0 +1,37 @@
1
+ import React, { useEffect } from "react";
2
+ import { useNostoContext } from "../Provider/context.client";
3
+
4
+ const NostoHome: React.FC = () => {
5
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
6
+ useEffect(() => {
7
+ if (currentVariation) {
8
+ console.log("currentVariation: ", currentVariation);
9
+ }
10
+ // @ts-ignore
11
+ if (clientScriptLoaded) {
12
+ window.nostojs((api: any) => {
13
+ api
14
+ .defaultSession()
15
+ .setVariation(currentVariation)
16
+ .setResponseMode("HTML")
17
+ .viewFrontPage()
18
+ .setPlacements(api.placements.getPlacements())
19
+ .load()
20
+ .then((data: object) => {
21
+ // @ts-ignore
22
+ api.placements.injectCampaigns(data.recommendations);
23
+ });
24
+ });
25
+ }
26
+ }, [clientScriptLoaded, currentVariation]);
27
+
28
+ return (
29
+ <>
30
+ <div className="nosto_page_type" style={{ display: "none" }}>
31
+ front
32
+ </div>
33
+ </>
34
+ );
35
+ };
36
+
37
+ export default NostoHome;
@@ -0,0 +1,43 @@
1
+ import { Purchase } from "../../types";
2
+ import React, { useEffect } from "react";
3
+ import snakeize from "snakeize";
4
+ import { useNostoContext } from "../Provider/context.client";
5
+
6
+ export interface OrderProps {
7
+ purchase: Purchase;
8
+ }
9
+
10
+ const NostoOrder: React.FC<{ order: OrderProps }> = ({ order }) => {
11
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
12
+ useEffect(() => {
13
+ // @ts-ignore
14
+ if (clientScriptLoaded) {
15
+ window.nostojs((api: any) => {
16
+ api
17
+ .defaultSession()
18
+ .setVariation(currentVariation)
19
+ .setResponseMode("HTML")
20
+ .addOrder(snakeize(order))
21
+ .setPlacements(api.placements.getPlacements())
22
+ .load()
23
+ .then((data: object) => {
24
+ // @ts-ignore
25
+ api.placements.injectCampaigns(data.recommendations);
26
+ });
27
+ });
28
+ }
29
+ }, [clientScriptLoaded, currentVariation]);
30
+
31
+ return (
32
+ <>
33
+ <div className="nosto_page_type" style={{ display: "none" }}>
34
+ order
35
+ </div>
36
+ <div className="nosto_order" style={{ display: "none" }}>
37
+ {order.purchase.number}
38
+ </div>
39
+ </>
40
+ );
41
+ };
42
+
43
+ export default NostoOrder;
@@ -0,0 +1,34 @@
1
+ import React, { useEffect } from "react";
2
+ import { useNostoContext } from "../Provider/context.client";
3
+
4
+ const NostoOther: React.FC = () => {
5
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
6
+ useEffect(() => {
7
+ // @ts-ignore
8
+ if (clientScriptLoaded) {
9
+ window.nostojs((api: any) => {
10
+ api
11
+ .defaultSession()
12
+ .setVariation(currentVariation)
13
+ .setResponseMode("HTML")
14
+ .viewOther()
15
+ .setPlacements(api.placements.getPlacements())
16
+ .load()
17
+ .then((data: object) => {
18
+ // @ts-ignore
19
+ api.placements.injectCampaigns(data.recommendations);
20
+ });
21
+ });
22
+ }
23
+ }, [clientScriptLoaded, currentVariation]);
24
+
25
+ return (
26
+ <>
27
+ <div className="nosto_page_type" style={{ display: "none" }}>
28
+ other
29
+ </div>
30
+ </>
31
+ );
32
+ };
33
+
34
+ export default NostoOther;
@@ -1,27 +1,30 @@
1
1
  import { Product } from "../../types";
2
- import stringinate from "../../utils/stringinate";
3
2
  import React, { useEffect } from "react";
4
- import snakeize from "snakeize";
3
+ import { useNostoContext } from "../Provider/context.client";
5
4
 
6
5
  const NostoProduct: React.FC<{ product: string; tagging: Product }> = ({
7
6
  product,
8
7
  tagging,
9
8
  }) => {
9
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
10
10
  useEffect(() => {
11
11
  // @ts-ignore
12
- window.nostojs((api) => {
13
- api
14
- .defaultSession()
15
- .setResponseMode("HTML")
16
- .viewProduct(snakeize(stringinate(tagging)))
17
- .setPlacements(api.placements.getPlacements())
18
- .load()
19
- .then((data: object) => {
20
- // @ts-ignore
21
- api.placements.injectCampaigns(data.recommendations);
22
- });
23
- });
24
- }, []);
12
+ if (clientScriptLoaded) {
13
+ window.nostojs((api: any) => {
14
+ api
15
+ .defaultSession()
16
+ .setVariation(currentVariation)
17
+ .setResponseMode("HTML")
18
+ .viewProduct(product)
19
+ .setPlacements(api.placements.getPlacements())
20
+ .load()
21
+ .then((data: object) => {
22
+ // @ts-ignore
23
+ api.placements.injectCampaigns(data.recommendations);
24
+ });
25
+ });
26
+ }
27
+ }, [clientScriptLoaded, currentVariation]);
25
28
 
26
29
  return (
27
30
  <>
@@ -29,81 +32,79 @@ const NostoProduct: React.FC<{ product: string; tagging: Product }> = ({
29
32
  product
30
33
  </div>
31
34
  <div className="nosto_product" style={{ display: "none" }}>
32
- {tagging.variationId && (
35
+ {tagging?.variationId && (
33
36
  <span className="variation_id">{tagging.variationId}</span>
34
37
  )}
35
- {tagging.productId && (
36
- <span className="product_id">{tagging.productId}</span>
37
- )}
38
- {tagging.name && <span className="name">{tagging.name}</span>}
39
- {tagging.url && <span className="url">{tagging.url.toString()}</span>}
40
- {tagging.imageUrl && (
38
+ {product && <span className="product_id">{product}</span>}
39
+ {tagging?.name && <span className="name">{tagging.name}</span>}
40
+ {tagging?.url && <span className="url">{tagging.url.toString()}</span>}
41
+ {tagging?.imageUrl && (
41
42
  <span className="image_url">{tagging.imageUrl.toString()}</span>
42
43
  )}
43
- {tagging.availability && (
44
+ {tagging?.availability && (
44
45
  <span className="availability">{tagging.availability}</span>
45
46
  )}
46
- {tagging.price && <span className="price">{tagging.price}</span>}
47
- {tagging.listPrice && (
47
+ {tagging?.price && <span className="price">{tagging.price}</span>}
48
+ {tagging?.listPrice && (
48
49
  <span className="list_price">{tagging.listPrice}</span>
49
50
  )}
50
- {tagging.priceCurrencyCode && (
51
+ {tagging?.priceCurrencyCode && (
51
52
  <span className="price_currency_code">
52
53
  {tagging.priceCurrencyCode}
53
54
  </span>
54
55
  )}
55
- {tagging.brand && <span className="brand">{tagging.brand}</span>}
56
- {tagging.description && (
56
+ {tagging?.brand && <span className="brand">{tagging.brand}</span>}
57
+ {tagging?.description && (
57
58
  <span className="description">{tagging.description}</span>
58
59
  )}
59
- {tagging.googleCategory && (
60
+ {tagging?.googleCategory && (
60
61
  <span className="description">{tagging.googleCategory}</span>
61
62
  )}
62
- {tagging.condition && (
63
+ {tagging?.condition && (
63
64
  <span className="condition">{tagging.condition}</span>
64
65
  )}
65
- {tagging.gender && <span className="gender">{tagging.gender}</span>}
66
- {tagging.ageGroup && (
66
+ {tagging?.gender && <span className="gender">{tagging.gender}</span>}
67
+ {tagging?.ageGroup && (
67
68
  <span className="age_group">{tagging.ageGroup}</span>
68
69
  )}
69
- {tagging.gtin && <span className="gtin">{tagging.gtin}</span>}
70
- {tagging.category &&
71
- tagging.category.map((category, index) => (
70
+ {tagging?.gtin && <span className="gtin">{tagging.gtin}</span>}
71
+ {tagging?.category &&
72
+ tagging?.category.map((category, index) => (
72
73
  <span className="category" key={index}>
73
74
  {category}
74
75
  </span>
75
76
  ))}
76
- {tagging.tags1 &&
77
+ {tagging?.tags1 &&
77
78
  tagging.tags1.map((tag, index) => (
78
79
  <span className="tag1" key={index}>
79
80
  {tag}
80
81
  </span>
81
82
  ))}
82
- {tagging.tags2 &&
83
+ {tagging?.tags2 &&
83
84
  tagging.tags2.map((tag, index) => (
84
85
  <span className="tag2" key={index}>
85
86
  {tag}
86
87
  </span>
87
88
  ))}
88
- {tagging.tags3 &&
89
+ {tagging?.tags3 &&
89
90
  tagging.tags3.map((tag, index) => (
90
91
  <span className="tag3" key={index}>
91
92
  {tag}
92
93
  </span>
93
94
  ))}
94
- {tagging.ratingValue && (
95
+ {tagging?.ratingValue && (
95
96
  <span className="rating_value">{tagging.ratingValue}</span>
96
97
  )}
97
- {tagging.reviewCount && (
98
+ {tagging?.reviewCount && (
98
99
  <span className="review_count">{tagging.reviewCount}</span>
99
100
  )}
100
- {tagging.alternateImageUrls &&
101
+ {tagging?.alternateImageUrls &&
101
102
  tagging.alternateImageUrls.map((url, index) => (
102
103
  <span className="alternate_image_url" key={index}>
103
104
  {url.toString()}
104
105
  </span>
105
106
  ))}
106
- {tagging.customFields &&
107
+ {tagging?.customFields &&
107
108
  Object.keys(tagging.customFields).map(
108
109
  (field, index) =>
109
110
  tagging.customFields &&
@@ -113,24 +114,24 @@ const NostoProduct: React.FC<{ product: string; tagging: Product }> = ({
113
114
  </span>
114
115
  )
115
116
  )}
116
- {tagging.skus &&
117
+ {tagging?.skus &&
117
118
  tagging.skus.map((sku, index) => (
118
119
  <span className="nosto_sku" key={index}>
119
- {sku.id && <span className="product_id">{sku.id}</span>}
120
- {sku.name && <span className="name">{sku.name}</span>}
121
- {sku.price && <span className="price">{sku.price}</span>}
122
- {sku.listPrice && (
120
+ {sku?.id && <span className="product_id">{sku.id}</span>}
121
+ {sku?.name && <span className="name">{sku.name}</span>}
122
+ {sku?.price && <span className="price">{sku.price}</span>}
123
+ {sku?.listPrice && (
123
124
  <span className="list_price">{sku.listPrice}</span>
124
125
  )}
125
- {sku.url && <span className="url">{sku.url.toString()}</span>}
126
- {sku.imageUrl && (
126
+ {sku?.url && <span className="url">{sku.url.toString()}</span>}
127
+ {sku?.imageUrl && (
127
128
  <span className="image_url">{sku.imageUrl.toString()}</span>
128
129
  )}
129
- {sku.gtin && <span className="gtin">{sku.gtin}</span>}
130
- {sku.availability && (
130
+ {sku?.gtin && <span className="gtin">{sku.gtin}</span>}
131
+ {sku?.availability && (
131
132
  <span className="availability">{sku.availability}</span>
132
133
  )}
133
- {sku.customFields &&
134
+ {sku?.customFields &&
134
135
  Object.keys(sku.customFields).map(
135
136
  (field, index) =>
136
137
  sku.customFields &&
@@ -0,0 +1,25 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ export interface NostoInterface {
4
+ account: string;
5
+ clientScriptLoaded: boolean;
6
+ currentVariation: string;
7
+ }
8
+
9
+ /* tslint:disable:no-empty */
10
+ export const NostoContext = createContext<NostoInterface>({
11
+ // @ts-ignore
12
+ account: undefined,
13
+ currentVariation: "",
14
+ });
15
+
16
+ /* tslint:enable:no-empty */
17
+ export function useNostoContext() {
18
+ const context = useContext(NostoContext);
19
+
20
+ if (!context) {
21
+ throw new Error("No nosto context found");
22
+ }
23
+
24
+ return context;
25
+ }
@@ -0,0 +1,58 @@
1
+ import React, { useEffect } from "react";
2
+ import { NostoContext } from "./context.client";
3
+
4
+ interface NostoProviderProps {
5
+ account: string;
6
+ currentVariation: string;
7
+ host: string;
8
+ children: React.ReactElement;
9
+ multiCurrency: boolean;
10
+ }
11
+
12
+ const NostoProvider: React.FC<NostoProviderProps> = ({
13
+ account,
14
+ currentVariation = "",
15
+ multiCurrency = false,
16
+ host,
17
+ children,
18
+ }) => {
19
+ const [clientScriptLoadedState, setClientScriptLoadedState] =
20
+ React.useState(false);
21
+ const clientScriptLoaded = React.useMemo(
22
+ () => clientScriptLoadedState,
23
+ [clientScriptLoadedState]
24
+ );
25
+
26
+ //Pass currentVariation as empty string if multiCurrency is disabled
27
+ currentVariation = multiCurrency ? currentVariation : "";
28
+
29
+ useEffect(() => {
30
+ if (!document.querySelectorAll("[nosto-client-script]").length) {
31
+ const script = document.createElement("script");
32
+ script.type = "text/javascript";
33
+ script.src = "//" + (host || "connect.nosto.com") + "/include/" + account;
34
+ script.async = true;
35
+ script.setAttribute("nosto-client-script", "");
36
+ script.onload = () => {
37
+ console.log("Nosto client script loaded");
38
+ setClientScriptLoadedState(true);
39
+ };
40
+ document.head.appendChild(script);
41
+ }
42
+
43
+ window.nostojs = (cb: Function) =>
44
+ (window.nostojs.q = window.nostojs.q || []).push(cb);
45
+ // @ts-ignore
46
+ window.nostojs((api) => api.setAutoLoad(false));
47
+ }, []);
48
+
49
+ return (
50
+ <NostoContext.Provider
51
+ value={{ account, clientScriptLoaded, currentVariation }}
52
+ >
53
+ {children}
54
+ </NostoContext.Provider>
55
+ );
56
+ };
57
+
58
+ export default NostoProvider;
@@ -0,0 +1,37 @@
1
+ import React, { useEffect } from "react";
2
+ import { useNostoContext } from "../Provider/context.client";
3
+
4
+ const NostoSearch: React.FC<{ query: string }> = ({ query }) => {
5
+ const { clientScriptLoaded, currentVariation } = useNostoContext();
6
+ useEffect(() => {
7
+ // @ts-ignore
8
+ if (clientScriptLoaded) {
9
+ window.nostojs((api: any) => {
10
+ api
11
+ .defaultSession()
12
+ .setVariation(currentVariation)
13
+ .setResponseMode("HTML")
14
+ .viewSearch(query)
15
+ .setPlacements(api.placements.getPlacements())
16
+ .load()
17
+ .then((data: object) => {
18
+ // @ts-ignore
19
+ api.placements.injectCampaigns(data.recommendations);
20
+ });
21
+ });
22
+ }
23
+ }, [clientScriptLoaded, currentVariation, query]);
24
+
25
+ return (
26
+ <>
27
+ <div className="nosto_page_type" style={{ display: "none" }}>
28
+ search
29
+ </div>
30
+ <div className="nosto_search" style={{ display: "none" }}>
31
+ {query}
32
+ </div>
33
+ </>
34
+ );
35
+ };
36
+
37
+ export default NostoSearch;
@@ -8,24 +8,30 @@ declare global {
8
8
 
9
9
  export * from "./types";
10
10
  // noinspection JSUnusedGlobalSymbols
11
- export { default as Nosto404 } from "./components/Fohofo";
11
+ export { default as Nosto404 } from "./components/Fohofo/index.client";
12
12
  // noinspection JSUnusedGlobalSymbols
13
- export { default as NostoOther } from "./components/Other";
13
+ export { default as NostoOther } from "./components/Other/index.client";
14
14
  // noinspection JSUnusedGlobalSymbols
15
- export { default as NostoCheckout } from "./components/Checkout";
15
+ export { default as NostoCheckout } from "./components/Checkout/index.client";
16
16
  // noinspection JSUnusedGlobalSymbols
17
- export { default as NostoProduct } from "./components/Product";
17
+ export { default as NostoProduct } from "./components/Product/index.client";
18
18
  // noinspection JSUnusedGlobalSymbols
19
- export { default as NostoCategory } from "./components/Category";
19
+ export { default as NostoCategory } from "./components/Category/index.client";
20
20
  // noinspection JSUnusedGlobalSymbols
21
- export { default as NostoSearch } from "./components/Search";
21
+ export { default as NostoSearch } from "./components/Search/index.client";
22
22
  // noinspection JSUnusedGlobalSymbols
23
- export { default as NostoOrder } from "./components/Order";
23
+ export { default as NostoOrder } from "./components/Order/index.client";
24
24
  // noinspection JSUnusedGlobalSymbols
25
- export { default as NostoHome } from "./components/Home";
25
+ export { default as NostoHome } from "./components/Home/index.client";
26
26
  // noinspection JSUnusedGlobalSymbols
27
- export { default as NostoPlacement } from "./components/Placement";
27
+ export { default as NostoPlacement } from "./components/Placement/index.client";
28
28
  // noinspection JSUnusedGlobalSymbols
29
- export { default as NostoProvider } from "./components/Provider";
29
+ export { default as NostoProvider } from "./components/Provider/index.client";
30
30
  // noinspection JSUnusedGlobalSymbols
31
- export { default as NostoSession } from "./components/Session";
31
+ export {
32
+ NostoContext,
33
+ useNostoContext,
34
+ } from "./components/Provider/context.client";
35
+ // noinspection JSUnusedGlobalSymbols
36
+ export { default as NostoSession } from "./components/Session/index.client";
37
+ //
@@ -1,32 +0,0 @@
1
- import React, { useEffect } from "react";
2
-
3
- const NostoCategory: React.FC<{ category: string }> = ({ category }) => {
4
- useEffect(() => {
5
- // @ts-ignore
6
- window.nostojs((api) => {
7
- api
8
- .defaultSession()
9
- .setResponseMode("HTML")
10
- .viewCategory(category)
11
- .setPlacements(api.placements.getPlacements())
12
- .load()
13
- .then((data: object) => {
14
- // @ts-ignore
15
- api.placements.injectCampaigns(data.recommendations);
16
- });
17
- });
18
- }, []);
19
-
20
- return (
21
- <>
22
- <div className="nosto_page_type" style={{ display: "none" }}>
23
- category
24
- </div>
25
- <div className="nosto_category" style={{ display: "none" }}>
26
- {category}
27
- </div>
28
- </>
29
- );
30
- };
31
-
32
- export default NostoCategory;
@@ -1,29 +0,0 @@
1
- import React, { useEffect } from "react";
2
-
3
- const NostoCheckout: React.FC = () => {
4
- useEffect(() => {
5
- // @ts-ignore
6
- window.nostojs((api) => {
7
- api
8
- .defaultSession()
9
- .setResponseMode("HTML")
10
- .viewCart()
11
- .setPlacements(api.placements.getPlacements())
12
- .load()
13
- .then((data: object) => {
14
- // @ts-ignore
15
- api.placements.injectCampaigns(data.recommendations);
16
- });
17
- });
18
- }, []);
19
-
20
- return (
21
- <>
22
- <div className="nosto_page_type" style={{ display: "none" }}>
23
- cart
24
- </div>
25
- </>
26
- );
27
- };
28
-
29
- export default NostoCheckout;
@@ -1,29 +0,0 @@
1
- import React, { useEffect } from "react";
2
-
3
- const NostoFohofo: React.FC = () => {
4
- useEffect(() => {
5
- // @ts-ignore
6
- window.nostojs((api) => {
7
- api
8
- .defaultSession()
9
- .setResponseMode("HTML")
10
- .viewNotFound()
11
- .setPlacements(api.placements.getPlacements())
12
- .load()
13
- .then((data: object) => {
14
- // @ts-ignore
15
- api.placements.injectCampaigns(data.recommendations);
16
- });
17
- });
18
- }, []);
19
-
20
- return (
21
- <>
22
- <div className="nosto_page_type" style={{ display: "none" }}>
23
- notfound
24
- </div>
25
- </>
26
- );
27
- };
28
-
29
- export default NostoFohofo;
@@ -1,29 +0,0 @@
1
- import React, { useEffect } from "react";
2
-
3
- const NostoHome: React.FC = () => {
4
- useEffect(() => {
5
- // @ts-ignore
6
- window.nostojs((api) => {
7
- api
8
- .defaultSession()
9
- .setResponseMode("HTML")
10
- .viewFrontPage()
11
- .setPlacements(api.placements.getPlacements())
12
- .load()
13
- .then((data: object) => {
14
- // @ts-ignore
15
- api.placements.injectCampaigns(data.recommendations);
16
- });
17
- });
18
- }, []);
19
-
20
- return (
21
- <>
22
- <div className="nosto_page_type" style={{ display: "none" }}>
23
- front
24
- </div>
25
- </>
26
- );
27
- };
28
-
29
- export default NostoHome;
@@ -1,38 +0,0 @@
1
- import { Purchase } from "../../types";
2
- import React, { useEffect } from "react";
3
- import snakeize from "snakeize";
4
-
5
- export interface OrderProps {
6
- purchase: Purchase;
7
- }
8
-
9
- const NostoOrder: React.FC<{ order: OrderProps }> = ({ order }) => {
10
- useEffect(() => {
11
- // @ts-ignore
12
- window.nostojs((api) => {
13
- api
14
- .defaultSession()
15
- .setResponseMode("HTML")
16
- .addOrder(snakeize(order))
17
- .setPlacements(api.placements.getPlacements())
18
- .load()
19
- .then((data: object) => {
20
- // @ts-ignore
21
- api.placements.injectCampaigns(data.recommendations);
22
- });
23
- });
24
- }, []);
25
-
26
- return (
27
- <>
28
- <div className="nosto_page_type" style={{ display: "none" }}>
29
- order
30
- </div>
31
- <div className="nosto_order" style={{ display: "none" }}>
32
- {order.purchase.number}
33
- </div>
34
- </>
35
- );
36
- };
37
-
38
- export default NostoOrder;