@bikdotai/bik-widgets 1.0.0

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.
Files changed (206) hide show
  1. package/.eslintrc +22 -0
  2. package/.eslintrc.js +19 -0
  3. package/.github/workflows/main.yml +293 -0
  4. package/.prettierignore +13 -0
  5. package/.prettierrc +10 -0
  6. package/README.md +128 -0
  7. package/cypress/apiHelper/endpoints.ts +21 -0
  8. package/cypress/apiHelper/executor.ts +42 -0
  9. package/cypress/e2e/bottomDrawer.cy.ts +49 -0
  10. package/cypress/e2e/directReward.cy.ts +67 -0
  11. package/cypress/e2e/scratchTheCard.cy.ts +68 -0
  12. package/cypress/e2e/stw.cy.ts +82 -0
  13. package/cypress/e2e/waRedirection.cy.ts +46 -0
  14. package/cypress/fixtures/payloads.ts +330 -0
  15. package/cypress/support/commands.ts +37 -0
  16. package/cypress/support/e2e.ts +20 -0
  17. package/cypress.staging.config.ts +23 -0
  18. package/jsconfig.json +6 -0
  19. package/localtest.sh +10 -0
  20. package/log-server.js +86 -0
  21. package/package.json +79 -0
  22. package/postcss.config.js +8 -0
  23. package/src/Globals.d.ts +2 -0
  24. package/src/assets/lottie/santa.json +11722 -0
  25. package/src/assets/svg/CalendarClockIcon.tsx +30 -0
  26. package/src/assets/svg/CalendarIcon.tsx +24 -0
  27. package/src/assets/svg/CheckIcon.tsx +17 -0
  28. package/src/assets/svg/ChevronIcon.tsx +21 -0
  29. package/src/assets/svg/Close.tsx +39 -0
  30. package/src/assets/svg/Confetti.tsx +140 -0
  31. package/src/assets/svg/Copy.tsx +26 -0
  32. package/src/assets/svg/DropdownCheckIcon.tsx +35 -0
  33. package/src/assets/svg/ErrorIcon.tsx +27 -0
  34. package/src/assets/svg/RadioIcon.tsx +25 -0
  35. package/src/assets/svg/UncheckedCheckboxIcon.tsx +28 -0
  36. package/src/assets/svg/UncheckedRadioIcon.tsx +26 -0
  37. package/src/assets/svg/info.tsx +30 -0
  38. package/src/assets/svg/qrcode.svg +14 -0
  39. package/src/bootstrap.tsx +8 -0
  40. package/src/components/CtaCard/index.tsx +37 -0
  41. package/src/components/CtaCard/preview.module.css +32 -0
  42. package/src/components/CtaCard/style.module.css +32 -0
  43. package/src/components/EmailInput/emailInputBox.tsx +95 -0
  44. package/src/components/Fab/index.tsx +224 -0
  45. package/src/components/Fab/preview.module.css +28 -0
  46. package/src/components/Fab/style.module.css +37 -0
  47. package/src/components/Icons/Call.tsx +26 -0
  48. package/src/components/Icons/Cross.tsx +24 -0
  49. package/src/components/Icons/Gmail.tsx +61 -0
  50. package/src/components/Icons/Instagram.tsx +60 -0
  51. package/src/components/Icons/LiveChat.tsx +43 -0
  52. package/src/components/Icons/Messenger.tsx +57 -0
  53. package/src/components/Icons/Send.tsx +22 -0
  54. package/src/components/Icons/Whatsapp.tsx +24 -0
  55. package/src/components/Shimmer/index.tsx +12 -0
  56. package/src/components/Shimmer/style.module.css +37 -0
  57. package/src/components/SmsInput/smsInputBox.tsx +135 -0
  58. package/src/components/UserDetailsV2/userDetailsV2.desktop.module.css +52 -0
  59. package/src/components/UserDetailsV2/userDetailsV2.mobile.module.css +52 -0
  60. package/src/components/UserDetailsV2/userDetailsV2.module.css +81 -0
  61. package/src/components/UserDetailsV2/userDetailsV2.tsx +527 -0
  62. package/src/components/WhatsappInput/Spinner.tsx +26 -0
  63. package/src/components/WhatsappInput/whatsappInput.module.css +106 -0
  64. package/src/components/WhatsappInput/whatsappInputBox.tsx +155 -0
  65. package/src/components/WhatsappInput/whatsappInputPreviewDesktop.module.css +71 -0
  66. package/src/components/WhatsappInput/whatsappInputPreviewMobile.module.css +65 -0
  67. package/src/components/checkbox/checkbox.module.css +19 -0
  68. package/src/components/checkbox/checkbox.tsx +88 -0
  69. package/src/components/countryCodePicker/countriesDropdown.module.css +77 -0
  70. package/src/components/countryCodePicker/countriesDropdown.tsx +81 -0
  71. package/src/components/couponDetails/coupon.module.css +208 -0
  72. package/src/components/couponDetails/coupon.tsx +210 -0
  73. package/src/components/couponDetails/couponPreviewDesktop.module.css +158 -0
  74. package/src/components/couponDetails/couponPreviewMobile.module.css +164 -0
  75. package/src/components/index.ts +3 -0
  76. package/src/components/inputComponents/Checkbox.module.css +197 -0
  77. package/src/components/inputComponents/Checkbox.tsx +85 -0
  78. package/src/components/inputComponents/DatePicker.module.css +565 -0
  79. package/src/components/inputComponents/DatePicker.tsx +278 -0
  80. package/src/components/inputComponents/Dropdown.module.css +796 -0
  81. package/src/components/inputComponents/Dropdown.tsx +630 -0
  82. package/src/components/inputComponents/InputBox.module.css +401 -0
  83. package/src/components/inputComponents/InputBox.tsx +209 -0
  84. package/src/components/selectedCountry/selectedCountry.module.css +76 -0
  85. package/src/components/selectedCountry/selectedCountry.tsx +76 -0
  86. package/src/components/selectedCountry/selectedCountryPreviewDesktop.module.css +56 -0
  87. package/src/components/selectedCountry/selectedCountryPreviewMobile.module.css +57 -0
  88. package/src/components/userDetailsForm/RenderCustomFields.tsx +333 -0
  89. package/src/components/userDetailsForm/userDetailsForm.tsx +675 -0
  90. package/src/hooks/index.ts +4 -0
  91. package/src/hooks/useExitIntent.ts +452 -0
  92. package/src/hooks/useIsMobile.tsx +21 -0
  93. package/src/hooks/useMessageEvent.ts +8 -0
  94. package/src/hooks/useTriggeredIntentDetails.ts +43 -0
  95. package/src/hooks/useUrlListerner.ts +30 -0
  96. package/src/hooks/useWebSocketLogger.ts +59 -0
  97. package/src/hooks/useWindowEvent.ts +8 -0
  98. package/src/icons/copyIcon.tsx +26 -0
  99. package/src/icons/crossIconDesktop.tsx +20 -0
  100. package/src/icons/crossIconMobile.tsx +20 -0
  101. package/src/index.html +30 -0
  102. package/src/index.ts +32 -0
  103. package/src/index.tsx +1 -0
  104. package/src/repo/widgetRepo.ts +21 -0
  105. package/src/types/customFields.ts +73 -0
  106. package/src/utilities/cookie.ts +70 -0
  107. package/src/utilities/customFieldTypeMapping.ts +67 -0
  108. package/src/utilities/customFieldValidation.ts +201 -0
  109. package/src/utilities/encryption.ts +21 -0
  110. package/src/utilities/exitIntentUtils.ts +31 -0
  111. package/src/utilities/global.css +11 -0
  112. package/src/utilities/languageUtilities.ts +235 -0
  113. package/src/utilities/localRunner.js +26 -0
  114. package/src/utilities/localRunner.ts +27 -0
  115. package/src/utilities/localStorage.ts +40 -0
  116. package/src/utilities/script.tsx +15 -0
  117. package/src/utilities/stringUtils.ts +5 -0
  118. package/src/utilities/styleUtils.ts +134 -0
  119. package/src/utilities/variables.ts +11 -0
  120. package/src/utilities/widgetUtils.js +342 -0
  121. package/src/utilities/widgetUtils.ts +313 -0
  122. package/src/widgets/BottomDrawer/config.ts +41 -0
  123. package/src/widgets/BottomDrawer/index.tsx +116 -0
  124. package/src/widgets/BottomDrawer/modal.tsx +286 -0
  125. package/src/widgets/BottomDrawer/preview.module.css +122 -0
  126. package/src/widgets/BottomDrawer/previewMobile.module.css +124 -0
  127. package/src/widgets/BottomDrawer/style.module.css +279 -0
  128. package/src/widgets/CaptivateBanner/captivateBanner.tsx +200 -0
  129. package/src/widgets/CaptivateBanner/config.ts +72 -0
  130. package/src/widgets/CaptivateBanner/index.tsx +204 -0
  131. package/src/widgets/CaptivateBanner/previewDesktop.module.css +51 -0
  132. package/src/widgets/CaptivateBanner/previewMobile.module.css +51 -0
  133. package/src/widgets/CaptivateBanner/style.module.css +77 -0
  134. package/src/widgets/CaptivateBanner/utils.ts +104 -0
  135. package/src/widgets/CentrallyAlignedPopup/config.ts +42 -0
  136. package/src/widgets/CentrallyAlignedPopup/index.tsx +109 -0
  137. package/src/widgets/CentrallyAlignedPopup/modal.tsx +269 -0
  138. package/src/widgets/CentrallyAlignedPopup/preview.module.css +153 -0
  139. package/src/widgets/CentrallyAlignedPopup/previewMobile.module.css +153 -0
  140. package/src/widgets/CentrallyAlignedPopup/style.module.css +283 -0
  141. package/src/widgets/DirectReward/components/couponDetails.tsx +265 -0
  142. package/src/widgets/DirectReward/components/userDetails.tsx +117 -0
  143. package/src/widgets/DirectReward/config.ts +186 -0
  144. package/src/widgets/DirectReward/directReward.tsx +350 -0
  145. package/src/widgets/DirectReward/index.tsx +579 -0
  146. package/src/widgets/DirectReward/previewStyles/thankYouPreviewDesktop.module.css +276 -0
  147. package/src/widgets/DirectReward/previewStyles/thankYouPreviewMobile.module.css +303 -0
  148. package/src/widgets/DirectReward/previewStyles/userDetailsPreviewDesktop.module.css +511 -0
  149. package/src/widgets/DirectReward/previewStyles/userDetailsPreviewMobile.module.css +462 -0
  150. package/src/widgets/DirectReward/style.module.css +836 -0
  151. package/src/widgets/ExitIntentHook.tsx +28 -0
  152. package/src/widgets/STW/api.ts +70 -0
  153. package/src/widgets/STW/components/svgFactory.tsx +44 -0
  154. package/src/widgets/STW/config.ts +193 -0
  155. package/src/widgets/STW/context.ts +7 -0
  156. package/src/widgets/STW/couponDetails.tsx +121 -0
  157. package/src/widgets/STW/index.tsx +733 -0
  158. package/src/widgets/STW/previewStyles/thankyouPreviewDesktop.module.css +215 -0
  159. package/src/widgets/STW/previewStyles/thankyouPreviewMobile.module.css +205 -0
  160. package/src/widgets/STW/previewStyles/userInputsPreviewDesktop.module.css +732 -0
  161. package/src/widgets/STW/previewStyles/userInputsPreviewMobile.module.css +661 -0
  162. package/src/widgets/STW/previewStyles/wheelPreviewDesktop.module.css +498 -0
  163. package/src/widgets/STW/previewStyles/wheelPreviewMobile.module.css +497 -0
  164. package/src/widgets/STW/stw1.tsx +119 -0
  165. package/src/widgets/STW/stw2Components/wheelDesign.tsx +183 -0
  166. package/src/widgets/STW/stw2Pages/couponDetails.tsx +72 -0
  167. package/src/widgets/STW/stw2Pages/stw2.tsx +212 -0
  168. package/src/widgets/STW/stw2Pages/style.module.css +1226 -0
  169. package/src/widgets/STW/stw2Pages/userDetails.tsx +86 -0
  170. package/src/widgets/STW/stw2Pages/wheel.tsx +117 -0
  171. package/src/widgets/STW/stw2PreviewStyles/thankyouPreviewDesktop.module.css +835 -0
  172. package/src/widgets/STW/stw2PreviewStyles/thankyouPreviewMobile.module.css +787 -0
  173. package/src/widgets/STW/stw2PreviewStyles/userInputsPreviewDesktop.module.css +867 -0
  174. package/src/widgets/STW/stw2PreviewStyles/userInputsPreviewMobile.module.css +798 -0
  175. package/src/widgets/STW/stw2PreviewStyles/wheelPreviewDesktop.module.css +572 -0
  176. package/src/widgets/STW/stw2PreviewStyles/wheelPreviewMobile.module.css +559 -0
  177. package/src/widgets/STW/style.module.css +901 -0
  178. package/src/widgets/STW/userDetails.tsx +150 -0
  179. package/src/widgets/STW/utility.ts +664 -0
  180. package/src/widgets/STW/wheel.tsx +304 -0
  181. package/src/widgets/ScratchCard/ScratchOff/scratchOff.tsx +157 -0
  182. package/src/widgets/ScratchCard/config.ts +152 -0
  183. package/src/widgets/ScratchCard/globalStyle.module.css +931 -0
  184. package/src/widgets/ScratchCard/index.tsx +546 -0
  185. package/src/widgets/ScratchCard/modal.tsx +225 -0
  186. package/src/widgets/ScratchCard/preview.module.css +250 -0
  187. package/src/widgets/ScratchCard/previewMobile.module.css +247 -0
  188. package/src/widgets/ScratchCard/previewStyles/userDetailsPreviewDesktop.module.css +537 -0
  189. package/src/widgets/ScratchCard/previewStyles/userDetailsPreviewMobile.module.css +463 -0
  190. package/src/widgets/ScratchCard/style.module.css +220 -0
  191. package/src/widgets/ShopifyForm/config.ts +168 -0
  192. package/src/widgets/ShopifyForm/index.tsx +214 -0
  193. package/src/widgets/ShopifyForm/previewDesktop.module.css +117 -0
  194. package/src/widgets/ShopifyForm/previewMobile.module.css +131 -0
  195. package/src/widgets/ShopifyForm/shopifyForm.tsx +445 -0
  196. package/src/widgets/ShopifyForm/style.module.css +161 -0
  197. package/src/widgets/SingleButtonRedirection/config.ts +47 -0
  198. package/src/widgets/SingleButtonRedirection/index.tsx +121 -0
  199. package/src/widgets/WebStories/config.ts +105 -0
  200. package/src/widgets/WebStories/index.css +3 -0
  201. package/src/widgets/WebStories/index.tsx +282 -0
  202. package/src/widgets/WebStories/style.module.css +26 -0
  203. package/src/widgets/index.tsx +3 -0
  204. package/src/widgets/utility.ts +31 -0
  205. package/tsconfig.json +12 -0
  206. package/webpack.config.js +239 -0
@@ -0,0 +1,121 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Fab } from 'components';
3
+ import includeMe from 'utilities/script';
4
+ import { IFab } from '../../components/Fab';
5
+ import Send from '../../components/Icons/Send';
6
+ import { IPageConfigProcessed, WidgetUtils } from '../../utilities/widgetUtils';
7
+ import { CookieUtils } from '../../utilities/cookie';
8
+ import { COOKIE_VALUES, EVENT_NAME } from '../../utilities/variables';
9
+ import {
10
+ IRedirectWidgetCustomisation,
11
+ WidgetSchema,
12
+ } from '@bikdotai/bik-models/dm';
13
+
14
+ export interface ISingleButtonRedirection extends WidgetSchema {
15
+ environment: string;
16
+ id: string;
17
+ storeWidgetConfig: IPageConfigProcessed;
18
+ preview?: boolean;
19
+ isMobile?: boolean;
20
+ }
21
+
22
+ const SingleButtonRedirection = (props: ISingleButtonRedirection) => {
23
+ const widgetUtils = new WidgetUtils();
24
+ const cookieUtils = new CookieUtils();
25
+ const environment = props.environment;
26
+ const widgetId = props.id;
27
+ const widgetCustomisation =
28
+ props.widgetCustomisation as IRedirectWidgetCustomisation;
29
+ const [showFab, setShowFab] = useState(false);
30
+ const [showWidget, setShowWidget] = useState(false);
31
+ let buttonStyle: React.CSSProperties;
32
+
33
+ if (widgetCustomisation?.fabText) {
34
+ buttonStyle = {
35
+ width: 'fit-content',
36
+ height: 'fit-content',
37
+ borderRadius: 20,
38
+ };
39
+ }
40
+
41
+ cookieUtils.addItemInLocalStorage('storeId', props.info?.storeId);
42
+
43
+ cookieUtils.cookieClickHandler(
44
+ `bik-${props.id}-visitor`,
45
+ COOKIE_VALUES.BIK_VISITOR,
46
+ EVENT_NAME.WIDGET_VISITED,
47
+ 1,
48
+ props.environment,
49
+ props.id,
50
+ );
51
+
52
+ useEffect(() => {
53
+ if (!props.preview) {
54
+ const shouldShow = widgetUtils.showWidget(
55
+ {
56
+ currentUrl: window.location.href.replace(window.location.origin, ''),
57
+ customUrls: props.storeWidgetConfig,
58
+ currentWidgetId: props.id,
59
+ },
60
+ props.info.isAutomationTesting,
61
+ );
62
+ setShowFab(shouldShow);
63
+ setShowWidget(shouldShow);
64
+ } else {
65
+ setShowFab(true);
66
+ }
67
+ }, [window.location.href]);
68
+
69
+ const fabStyle: IFab = {
70
+ icon: <Send color={widgetCustomisation?.iconColor} />,
71
+ onClick() {
72
+ cookieUtils.cookieClickHandler(
73
+ `bik-${props.id}-clicked`,
74
+ 'bikclick',
75
+ 'WIDGET_CLICKED',
76
+ 1,
77
+ props.environment,
78
+ props.id,
79
+ );
80
+ const pathName = location.href.replace(location.origin, '');
81
+ //temp feat for liv-space. need to make it generic.
82
+ const isMobileApp = window.navigator.userAgent.includes('livspace-app');
83
+ window.open(
84
+ `${environment}/publicApiFunctions-redirectToChat/?contextType=bik-widgets&contextId=${widgetId}&pathname=${encodeURIComponent(pathName)}&sourceUrl=${location.href}&platform=${isMobileApp ? 'app' : 'web'}`,
85
+ );
86
+ },
87
+ buttonStyle: buttonStyle,
88
+ isMobile: props.isMobile,
89
+ preview: props.preview ?? false,
90
+ widgetCustomisation: {
91
+ fabText: widgetCustomisation?.fabText,
92
+ iconColor: widgetCustomisation?.iconColor,
93
+ fabTransform: widgetCustomisation?.fabTransform,
94
+ fabPositioner: widgetCustomisation?.fabPositioner,
95
+ fabBackgroundColor: widgetCustomisation?.fabBackgroundColor,
96
+ fabLottie: widgetCustomisation?.fabLottie,
97
+ fabAnimationRun: widgetCustomisation?.fabAnimationRun,
98
+ fabImage: widgetCustomisation?.fabImage,
99
+ fabIconLink: widgetCustomisation?.fabIconLink,
100
+ fabWebSize: widgetCustomisation?.fabWebSize,
101
+ fabMobileSize: widgetCustomisation?.fabMobileSize,
102
+ multiLingualConfigurations:
103
+ widgetCustomisation?.multiLingualConfigurations,
104
+ } as IRedirectWidgetCustomisation,
105
+ } as IFab;
106
+ return (
107
+ <>
108
+ {showWidget && (
109
+ <div id={`bik-widget-root-${props.id}`}>
110
+ {showFab && <Fab {...fabStyle} id={`bik-wa-${props.id}-cta`} />}
111
+ </div>
112
+ )}
113
+ </>
114
+ );
115
+ };
116
+
117
+ export default SingleButtonRedirection;
118
+
119
+ if (process.env.NODE_ENV !== 'development') {
120
+ includeMe(SingleButtonRedirection);
121
+ }
@@ -0,0 +1,105 @@
1
+ import { IWebStories } from './index';
2
+ const config: IWebStories = {
3
+ storeId: 'p60HYv5wjgQaOrPdqT5NjbpkroD2',
4
+ idToken: '',
5
+ widgetId: 'h19TPIIt2VmqzQ0S7dnu',
6
+ environment: 'https://api.staging.bik.ai/qa-dm',
7
+
8
+ widgetCustomisation: {
9
+ widgetName: 'undefined 53',
10
+ name: 'Story widget',
11
+ storyCollectionThumbnailConfig: {
12
+ shape: 'CIRCLE',
13
+ borderColor: '#B01228',
14
+ },
15
+ storyCollections: [
16
+ {
17
+ index: 0,
18
+ htmlSource:
19
+ 'https://storage.googleapis.com/bik-widget-mfe/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/html/1bfad35764',
20
+ thumbnail:
21
+ 'https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/insta_logo.jpeg',
22
+ name: 'Collection name',
23
+ id: 'collectionId1',
24
+ stories: [
25
+ {
26
+ index: 0,
27
+ ref: 'https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/wallpaper.jpeg',
28
+ fileName: 'honey_bee_busy_insect_flower_bee_659.mp4 ',
29
+ type: 'video',
30
+ ctaButton: {
31
+ buttonText: 'Buy it',
32
+ redirectionLink: 'https://www.bik.ai',
33
+ backgroundColor: '#365e7c',
34
+ },
35
+ },
36
+ ],
37
+ },
38
+ {
39
+ index: 1,
40
+ htmlSource:
41
+ 'https://storage.googleapis.com/bik-widget-mfe/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/6Hx8RbBpFn83Fbz4T9fj/html/f4dda2fd98',
42
+ thumbnail:
43
+ 'https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/insta_logo.jpeg',
44
+ name: 'Collection name 2',
45
+ id: 'collectionId2',
46
+ stories: [
47
+ {
48
+ index: 0,
49
+ ref: 'https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/wallpaper.jpeg',
50
+ fileName: 'honey_bee_busy_insect_flower_bee_659.mp4 ',
51
+ type: 'video',
52
+ ctaButton: {
53
+ buttonText: 'Buy it',
54
+ redirectionLink: 'https://www.bik.ai',
55
+ backgroundColor: '#365e7c',
56
+ },
57
+ },
58
+ ],
59
+ },
60
+ ],
61
+ },
62
+ // content: {
63
+ // widgetCustomisation: {
64
+ // widgetName: "undefined 53",
65
+ // name: "Story widget",
66
+ // storyCollections: [
67
+ // {
68
+ // index: 0,
69
+ // htmlSource: 'https://storage.googleapis.com/bik-widget-mfe/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/html/1bfad35764',
70
+ // thumbnail: "https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/insta_logo.jpeg",
71
+ // name: "Collection name",
72
+ // stories: [
73
+ // {
74
+ // index: 0,
75
+ // ref: "https://api.staging.bik.ai/bik-widgets/bap/web-stories/p60HYv5wjgQaOrPdqT5NjbpkroD2/h19TPIIt2VmqzQ0S7dnu/assets/wallpaper.jpeg",
76
+ // fileName: "wallpaper.jpeg",
77
+ // type: "image",
78
+ // ctaButton: {
79
+ // buttonText: "Shop now",
80
+ // redirectionLink: "https://www.bik.ai",
81
+ // backgroundColor: "#365e7c"
82
+ // }
83
+ // }
84
+ // ]
85
+ // }
86
+ // ]
87
+ // },
88
+ // visibility: {},
89
+ // leadGeneration: {},
90
+ // info: {
91
+ // templateNam: "WEB_STORIES_ON_WEBSITE",
92
+ // delete: false,
93
+ // status: "DRAFT",
94
+ // liveSince: null,
95
+ // templateId: "RfOLW0L9ZtjNPnQmFg8V",
96
+ // infra: "2.0",
97
+ // widgetTypeId: "uEv8pVPCMSlSM2EjLXlT",
98
+ // storeId: "p60HYv5wjgQaOrPdqT5NjbpkroD2",
99
+ // scriptPath: "",
100
+ // widgetId: "h19TPIIt2VmqzQ0S7dnu"
101
+ // }
102
+ // }
103
+ };
104
+
105
+ export default config;
@@ -0,0 +1,3 @@
1
+ .i-amphtml-fill-content {
2
+ display: block !important;
3
+ }
@@ -0,0 +1,282 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import Style from './style.module.css';
4
+ import './index.css';
5
+ import { IPageConfigProcessed } from 'utilities/widgetUtils';
6
+ import { COOKIE_VALUES, EVENT_NAME } from '../../utilities/variables';
7
+ import { CookieUtils } from '../../utilities/cookie';
8
+ import Shimmer from '../../components/Shimmer';
9
+ import { WidgetSchema } from '@bikdotai/bik-models/dm';
10
+
11
+ export interface IWebStories extends WidgetSchema {
12
+ id?: string;
13
+ environment: string;
14
+ preview?: boolean;
15
+ isMobile?: boolean;
16
+ storeWidgetConfig: IPageConfigProcessed;
17
+ }
18
+
19
+ const ampStoryPlayerUrl = 'https://cdn.ampproject.org/amp-story-player-v0';
20
+ const config = {
21
+ behavior: {
22
+ autoplay: false,
23
+ },
24
+ controls: [
25
+ {
26
+ name: 'close',
27
+ position: 'start',
28
+ },
29
+ ],
30
+ };
31
+
32
+ function getAmpScript(callback) {
33
+ const ampJS = document.createElement('script');
34
+ ampJS.async = true;
35
+ ampJS.src = ampStoryPlayerUrl + '.js';
36
+ ampJS.onload = callback;
37
+ return ampJS;
38
+ }
39
+
40
+ function getAmpCss() {
41
+ const ampCSS = document.createElement('link');
42
+ ampCSS.href = ampStoryPlayerUrl + '.css';
43
+ ampCSS.rel = 'stylesheet';
44
+ ampCSS.type = 'text/css';
45
+
46
+ return ampCSS;
47
+ }
48
+
49
+ const useAmpStoryPlayer = callback => {
50
+ useEffect(() => {
51
+ const ampScript = document.querySelector(
52
+ `script[src="${ampStoryPlayerUrl + '.js'}"]`,
53
+ );
54
+ if (!ampScript) {
55
+ document.head.appendChild(getAmpScript(callback));
56
+ document.head.appendChild(getAmpCss());
57
+ }
58
+ }, []);
59
+ };
60
+
61
+ const WebStories = (props: IWebStories) => {
62
+ const storyCollection = props.widgetCustomisation?.storyCollections ?? [];
63
+ let htmlSources = [];
64
+ storyCollection.forEach(collection => {
65
+ htmlSources.push({ href: collection.htmlSource });
66
+ });
67
+ const thumbnailConfig =
68
+ props.widgetCustomisation?.storyCollectionThumbnailConfig ?? {};
69
+ const cookieUtils = new CookieUtils();
70
+ const [playerRef, setPlayerRef] = useState(null);
71
+ const [showPlayer, setShowPlayer] = useState(false);
72
+ const [showLoader, setShowLoader] = useState(true);
73
+ const [currentCollectionIndex, setCurrentCollectionIndex] = useState(0);
74
+
75
+ cookieUtils.addItemInLocalStorage('storeId', props.info?.storeId);
76
+
77
+ cookieUtils.cookieClickHandler(
78
+ `bik-${props.id}-visitor`,
79
+ COOKIE_VALUES.BIK_VISITOR,
80
+ EVENT_NAME.WIDGET_VISITED,
81
+ 1,
82
+ props.environment,
83
+ props.id ?? '-1',
84
+ );
85
+
86
+ const saveViewedStories = (stories: string[]) => {
87
+ const date = new Date();
88
+ date.setTime(date.getTime() + 24 * 60 * 60 * 1000);
89
+ const expires = 'expires=' + date.toUTCString();
90
+ document.cookie =
91
+ 'arrayCookie=' + JSON.stringify(stories) + ';' + expires + ';path=/';
92
+ };
93
+
94
+ const clearStoriesCookie = () => {
95
+ document.cookie =
96
+ 'arrayCookie=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
97
+ };
98
+
99
+ const retrieveStoriesFromCookie = () => {
100
+ const name = 'arrayCookie=';
101
+ const decodedCookie = decodeURIComponent(document.cookie);
102
+ const ca = decodedCookie.split(';');
103
+ for (let i = 0; i < ca.length; i++) {
104
+ let c = ca[i];
105
+ while (c.charAt(0) === ' ') {
106
+ c = c.substring(1);
107
+ }
108
+ if (c.indexOf(name) === 0) {
109
+ return JSON.parse(c.substring(name.length, c.length));
110
+ }
111
+ }
112
+ return [];
113
+ };
114
+ const savedStories = retrieveStoriesFromCookie();
115
+
116
+ const loadPlayer = () => () => {
117
+ const player = document.querySelector('amp-story-player');
118
+ window.player = player;
119
+ setPlayerRef(player);
120
+
121
+ if (player.isReady) {
122
+ addStories(player);
123
+ } else {
124
+ player.addEventListener('ready', () => {
125
+ console.log('player is ready');
126
+ addStories(player);
127
+ });
128
+ }
129
+ };
130
+
131
+ const addStories = player => {
132
+ setShowLoader(false);
133
+ player.add(htmlSources);
134
+ player.addEventListener('storyNavigation', event => {
135
+ const detail = event.detail;
136
+ cookieUtils.cookieClickHandler(
137
+ `bik-${props.id}-story-viewed`,
138
+ COOKIE_VALUES.STORY_VIEWED,
139
+ EVENT_NAME.STORY_VIEWED,
140
+ 1,
141
+ props.environment,
142
+ props.id ?? -1,
143
+ {
144
+ collectionId: storyCollection[currentCollectionIndex].id,
145
+ storyId: detail.pageId,
146
+ },
147
+ );
148
+ });
149
+ player.addEventListener('navigation', event => {
150
+ const index = event.detail.index;
151
+ setCurrentCollectionIndex(index);
152
+ const isSaved = savedStories.includes(
153
+ `web-story-${storyCollection[index].id}`,
154
+ );
155
+ const temp = retrieveStoriesFromCookie();
156
+ if (!isSaved) {
157
+ saveViewedStories([...temp, `web-story-${storyCollection[index].id}`]);
158
+ }
159
+ cookieUtils.cookieClickHandler(
160
+ `bik-${props.id}-collection-viewed`,
161
+ COOKIE_VALUES.COLLECTION_VIEWED,
162
+ EVENT_NAME.COLLECTION_VIEWED,
163
+ 1,
164
+ props.environment,
165
+ props.id ?? -1,
166
+ {
167
+ collectionId: storyCollection[index].id,
168
+ },
169
+ );
170
+ });
171
+ player.addEventListener('amp-story-player-close', () => {
172
+ closePlayer(player);
173
+ });
174
+ };
175
+
176
+ useAmpStoryPlayer(loadPlayer(playerRef));
177
+
178
+ const closePlayer = player => {
179
+ player.pause();
180
+ setShowPlayer(false);
181
+ };
182
+
183
+ const handleShow = idx => {
184
+ cookieUtils.cookieClickHandler(
185
+ `bik-${props.id}-collection-viewed`,
186
+ COOKIE_VALUES.COLLECTION_VIEWED,
187
+ EVENT_NAME.COLLECTION_VIEWED,
188
+ 1,
189
+ props.environment,
190
+ props.id,
191
+ {
192
+ collectionId: storyCollection[idx].id,
193
+ },
194
+ );
195
+ const stories = playerRef.getStories();
196
+ playerRef.show(stories[idx].href);
197
+ playerRef.play();
198
+ setShowPlayer(true);
199
+ };
200
+
201
+ return (
202
+ <>
203
+ {storyCollection.length === 0 ? (
204
+ <div style={{ margin: 16, display: 'flex', gap: 24 }}>
205
+ <Shimmer
206
+ shimmerStyle={{
207
+ width: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 64,
208
+ height: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 96,
209
+ borderRadius: thumbnailConfig?.shape === 'CIRCLE' ? '50%' : 4,
210
+ }}
211
+ />
212
+ <Shimmer
213
+ shimmerStyle={{
214
+ width: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 64,
215
+ height: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 96,
216
+ borderRadius: thumbnailConfig?.shape === 'CIRCLE' ? '50%' : 4,
217
+ }}
218
+ />
219
+ </div>
220
+ ) : (
221
+ <div style={{ overflow: 'auto', whiteSpace: 'nowrap' }}>
222
+ {storyCollection.map((collection, index) => {
223
+ const isSaved = savedStories.includes(`web-story-${collection.id}`);
224
+ const borderWidth = isSaved ? 0 : 2;
225
+ return (
226
+ <button
227
+ id={`web-story-${collection.id}`}
228
+ onClick={e => {
229
+ handleShow(index);
230
+ if (!isSaved) {
231
+ saveViewedStories([
232
+ ...savedStories,
233
+ `web-story-${collection.id}`,
234
+ ]);
235
+ }
236
+ }}
237
+ style={{
238
+ cursor: 'pointer',
239
+ margin: 8,
240
+ border: 'none',
241
+ background: 'none',
242
+ display: 'inline-block',
243
+ }}
244
+ >
245
+ <img
246
+ style={{
247
+ width: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 64,
248
+ height: thumbnailConfig?.shape === 'CIRCLE' ? 80 : 96,
249
+ cursor: 'pointer',
250
+ objectFit: 'cover',
251
+ padding: 2,
252
+ borderRadius:
253
+ thumbnailConfig?.shape === 'CIRCLE' ? '50%' : 4,
254
+ border: `${borderWidth}px solid ${thumbnailConfig.borderColor}`,
255
+ }}
256
+ src={collection.thumbnail}
257
+ />
258
+ </button>
259
+ );
260
+ })}
261
+ </div>
262
+ )}
263
+
264
+ <div className={`${showPlayer ? Style.lightboxShow : Style.lightbox}`}>
265
+ <amp-story-player style={{ width: '100vw', height: '100vh' }}>
266
+ <script
267
+ type="application/json"
268
+ // eslint-disable-next-line react/no-danger
269
+ dangerouslySetInnerHTML={{
270
+ __html: JSON.stringify(config),
271
+ }}
272
+ />
273
+ </amp-story-player>
274
+ </div>
275
+ </>
276
+ );
277
+ };
278
+
279
+ export default WebStories;
280
+
281
+ const widget = document.getElementById(`bik-web-story-widget-wrapper`);
282
+ ReactDOM.render(<WebStories {...JSON.parse('{{{bikConfig}}}')} />, widget);
@@ -0,0 +1,26 @@
1
+ .lightbox {
2
+ position: absolute;
3
+ background-color: rgb(0, 0, 0, 0.7);
4
+ z-index: -99999;
5
+ top: 0;
6
+ bottom: 0;
7
+ right: 0;
8
+ left: 0;
9
+ opacity: 0;
10
+ visibility: hidden;
11
+ transition:
12
+ visibility 0.2s linear,
13
+ opacity 0.2s linear;
14
+ }
15
+
16
+ .lightboxShow {
17
+ position: absolute;
18
+ visibility: visible;
19
+ z-index: 99999;
20
+ background-color: rgb(0, 0, 0, 0.7);
21
+ top: 0;
22
+ bottom: 0;
23
+ right: 0;
24
+ left: 0;
25
+ opacity: 1;
26
+ }
@@ -0,0 +1,3 @@
1
+ import CentrallyAlignedPopup from 'widgets/CentrallyAlignedPopup';
2
+
3
+ export { CentrallyAlignedPopup };
@@ -0,0 +1,31 @@
1
+ import { TRIGGERED_PAGE_TYPE } from '@bikdotai/bik-models/dm/models/analytics';
2
+
3
+ export const decodeTextHelper = (text: string) => {
4
+ try {
5
+ return decodeURIComponent(text);
6
+ } catch (err: any) {
7
+ return text;
8
+ }
9
+ };
10
+
11
+ export const getStyles = url => {
12
+ return new Promise(function (resolve, reject) {
13
+ import(`${url}`).then(async style => {
14
+ resolve(style);
15
+ });
16
+ });
17
+ };
18
+
19
+ export const getTriggeredPageFromUrl = (url: string): TRIGGERED_PAGE_TYPE => {
20
+ try {
21
+ const urlObj = new URL(url);
22
+ const segments = urlObj.pathname.split('/').filter(Boolean);
23
+
24
+ if (segments.length === 0) return TRIGGERED_PAGE_TYPE.HOME;
25
+ if (segments[0] === 'collections') return TRIGGERED_PAGE_TYPE.COLLECTION;
26
+ if (segments[0] === 'products') return TRIGGERED_PAGE_TYPE.PRODUCT;
27
+ return TRIGGERED_PAGE_TYPE.CUSTOM;
28
+ } catch (error) {
29
+ return TRIGGERED_PAGE_TYPE.CUSTOM;
30
+ }
31
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "jsx": "preserve",
4
+ "skipLibCheck": true,
5
+ "baseUrl": "./src",
6
+ "paths": {
7
+ "react": ["./node_modules/preact/compat/"],
8
+ "react-dom": ["./node_modules/preact/compat/"]
9
+ },
10
+ "allowSyntheticDefaultImports": true
11
+ }
12
+ }