@cuemath/web-utils 0.0.2-beta.1 → 0.0.2-beta.10

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 (65) hide show
  1. package/.eslintignore +2 -0
  2. package/.husky/pre-commit +1 -0
  3. package/.huskyrc +5 -0
  4. package/.lintstagedrc.yml +5 -0
  5. package/dist/index.js +6 -1
  6. package/package.json +19 -8
  7. package/src/constants/country/index.ts +2 -0
  8. package/src/constants/country/iso-country-code.ts +248 -0
  9. package/src/constants/date-time/index.ts +43 -0
  10. package/src/constants/date-time/international-timezones.ts +157 -0
  11. package/src/constants/e-cna/index.ts +55 -0
  12. package/src/constants/index.ts +2 -0
  13. package/src/cookie/index.ts +4 -10
  14. package/src/country/index.ts +9 -0
  15. package/src/date-time-helper/e-cna.ts +205 -0
  16. package/src/date-time-helper/index.ts +365 -0
  17. package/src/e-cna/flow/aggregator.ts +12 -0
  18. package/src/e-cna/flow/index.ts +1 -0
  19. package/src/e-cna/flow/variants/default.ts +113 -0
  20. package/src/e-cna/flow/variants/index.ts +1 -0
  21. package/src/e-cna/index.ts +249 -0
  22. package/src/e-cna/slides/child_hobbies/index.ts +1 -0
  23. package/src/e-cna/slides/child_hobbies/variants.ts +24 -0
  24. package/src/e-cna/slides/child_info/index.ts +1 -0
  25. package/src/e-cna/slides/child_info/variants.ts +18 -0
  26. package/src/e-cna/slides/child_personality/index.ts +1 -0
  27. package/src/e-cna/slides/child_personality/variants.ts +12 -0
  28. package/src/e-cna/slides/curriculum/index.ts +1 -0
  29. package/src/e-cna/slides/curriculum/variants.ts +14 -0
  30. package/src/e-cna/slides/grade/index.ts +1 -0
  31. package/src/e-cna/slides/grade/variants.ts +29 -0
  32. package/src/e-cna/slides/index.ts +19 -0
  33. package/src/e-cna/slides/intro/index.ts +1 -0
  34. package/src/e-cna/slides/intro/variants.ts +7 -0
  35. package/src/e-cna/slides/key_need_l1/index.ts +1 -0
  36. package/src/e-cna/slides/key_need_l1/variants.ts +57 -0
  37. package/src/e-cna/slides/key_need_l2/index.ts +1 -0
  38. package/src/e-cna/slides/key_need_l2/variants.ts +143 -0
  39. package/src/e-cna/slides/key_need_l3/index.ts +1 -0
  40. package/src/e-cna/slides/key_need_l3/variants.ts +13 -0
  41. package/src/e-cna/slides/math-perception/index.ts +1 -0
  42. package/src/e-cna/slides/math-perception/variants.ts +30 -0
  43. package/src/e-cna/slides/other_curriculum/index.ts +1 -0
  44. package/src/e-cna/slides/other_curriculum/variants.ts +14 -0
  45. package/src/e-cna/slides/school_performance_5_12/index.ts +1 -0
  46. package/src/e-cna/slides/school_performance_5_12/variants.ts +23 -0
  47. package/src/e-cna/slides/school_performance_kg_4/index.ts +1 -0
  48. package/src/e-cna/slides/school_performance_kg_4/variants.ts +25 -0
  49. package/src/e-cna/slides/secondary_needs/index.ts +1 -0
  50. package/src/e-cna/slides/secondary_needs/variants.ts +26 -0
  51. package/src/e-cna/slides/signup/index.ts +1 -0
  52. package/src/e-cna/slides/signup/variants.ts +7 -0
  53. package/src/e-cna/slides/signup_refer/index.ts +1 -0
  54. package/src/e-cna/slides/signup_refer/variants.ts +16 -0
  55. package/src/e-cna/slides/slot_pick/index.ts +1 -0
  56. package/src/e-cna/slides/slot_pick/variants.ts +12 -0
  57. package/src/e-cna/slides/teacher_intro/index.ts +1 -0
  58. package/src/e-cna/slides/teacher_intro/variants.ts +114 -0
  59. package/src/e-cna/utils/index.ts +32 -0
  60. package/src/index.ts +6 -1
  61. package/src/local-storage/index.ts +186 -0
  62. package/src/object/index.ts +26 -0
  63. package/.vscode/settings.json +0 -1
  64. package/src/growth-source/index.ts +0 -172
  65. package/src/growth-source/types.ts +0 -33
@@ -0,0 +1,23 @@
1
+ export const school_performance_5_12 = {
2
+ DEFAULT: {
3
+ id: 3,
4
+ questionID: 'school_performance_5_12',
5
+ type: 'options',
6
+ question: 'How did they perform at school on their last assessment?',
7
+ description:
8
+ "Don't worry, we're just trying to understand what would work best for your child, so we can recommend the right program!",
9
+ options: [
10
+ { value: 'BELOW 70%', logo: '/static/e-cna-form/one-star.svg' },
11
+ {
12
+ value: '70% TO 90%',
13
+ logo: '/static/e-cna-form/two-stars.svg',
14
+ },
15
+ {
16
+ value: 'ABOVE 90%',
17
+ logo: '/static/e-cna-form/three-stars.svg',
18
+ },
19
+ ],
20
+ defaultNextquestionID: 'key_need_l1',
21
+ questionUUID: 'eea3d36a-405d-47f3-ba23-ef748bc24298',
22
+ },
23
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,25 @@
1
+ export const school_performance_kg_4 = {
2
+ DEFAULT: {
3
+ id: 4,
4
+ questionID: 'school_performance_kg_4',
5
+ type: 'options_thin',
6
+ question: "What does your child's teacher say about math performance at school?",
7
+ options: [
8
+ {
9
+ value: "Can improve. You've got potential.",
10
+ logo: '/static/e-cna-form/one-star.svg',
11
+ },
12
+ {
13
+ value: 'Pretty good but you can do even better',
14
+ logo: '/static/e-cna-form/two-stars.svg',
15
+ },
16
+ {
17
+ value: "Awesome job! You're on track!",
18
+ logo: '/static/e-cna-form/three-stars.svg',
19
+ },
20
+ ],
21
+
22
+ defaultNextquestionID: 'key_need_l1',
23
+ questionUUID: 'a3fdfdf8-6d34-42b9-8bbe-d9568b797881',
24
+ },
25
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,26 @@
1
+ const getSecondaryKeyNeeds = () => [
2
+ {
3
+ value:
4
+ "I'd like them to build strong math foundation and get support for schoolwork.",
5
+ },
6
+ { value: "I'd like them to be faster at calculations / Mental math." },
7
+ { value: "I'd like them to bridge learning gaps from previous and current grades." },
8
+ { value: 'I want my child to practice math regulalry.' },
9
+ { value: "I'd like them to develop interest and start enjoying math without fear." },
10
+ { value: 'I want my child to practice advanced and competitive math.' },
11
+ ];
12
+
13
+ export const secondary_needs = {
14
+ DEFAULT: {
15
+ id: 13,
16
+ questionID: 'secondary_needs',
17
+ type: 'options_multiselect',
18
+ question: 'Is there anything else we should focus on?',
19
+ description: 'You can select more than 1.',
20
+ get options() {
21
+ return getSecondaryKeyNeeds();
22
+ },
23
+ defaultNextquestionID: 'child_personality',
24
+ questionUUID: '4e1830f2-d37d-4c6f-9e56-1bd1e6660984',
25
+ },
26
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,7 @@
1
+ export const signup = {
2
+ DEFAULT: {
3
+ id: 'parent_student_details',
4
+ questionID: 'demo',
5
+ nextSlide: 'parent_student_details',
6
+ },
7
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,16 @@
1
+ export const signup_refer = {
2
+ DEFAULT: {
3
+ id: 16,
4
+ questionID: 'signup_refer',
5
+ type: 'options',
6
+ question: 'How did you learn about Cuemath?',
7
+ options: [
8
+ { value: 'Friends/Family' },
9
+ { value: 'Online Search' },
10
+ { value: 'Social Media' },
11
+ { value: 'App Store/Play Store' },
12
+ { value: 'Others' },
13
+ ],
14
+ questionUUID: 'ea8f4ed7-4214-4dcd-a818-701bf1843626',
15
+ },
16
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,12 @@
1
+ export const slot_pick = {
2
+ DEFAULT: {
3
+ id: 'slot_pick',
4
+ questionID: 'demo',
5
+ nextSlide: 'parent_student_details',
6
+ },
7
+ NON_ECNA: {
8
+ id: 'slot_pick',
9
+ questionID: 'demo',
10
+ nextSlide: 'parent_details',
11
+ },
12
+ };
@@ -0,0 +1 @@
1
+ export * from './variants';
@@ -0,0 +1,114 @@
1
+ export const t_led_flow = {
2
+ DEFAULT: {
3
+ id: 'teacher_intro',
4
+ questionID: 'teacherId',
5
+ nextSlide: 'question',
6
+ },
7
+ GRADE: {
8
+ id: 1,
9
+ questionID: 'student_grade',
10
+ type: 'options_grid',
11
+ question: 'What grade is your child in?',
12
+ description:
13
+ "We'll use this information to surface the right recommendations in the next few questions.",
14
+ options: [
15
+ { value: '10' },
16
+ { value: '11' },
17
+ { value: '12' },
18
+ { value: '7' },
19
+ { value: '8' },
20
+ { value: '9' },
21
+ { value: '4' },
22
+ { value: '5' },
23
+ { value: '6' },
24
+ { value: '1' },
25
+ { value: '2' },
26
+ { value: '3' },
27
+ { value: 'KG' },
28
+ ], // Options
29
+ defaultNextquestionID: 'child_info', // submit issue
30
+ // defaultNextquestionID: 'hybrid_teacher',
31
+ // questionUUID: '3d8688bf-ad00-4cbf-a5f9-ba9cac27af46',
32
+ },
33
+ // CHILD_INFO: { // for other flow
34
+ // id: 'child_info',
35
+ // questionID: 'child_info',
36
+ // nextSlide: 'teacher_not_available',
37
+ // },
38
+ // TEACHER_NOT_AVAILABLE:{
39
+ // id: 'teacher_not_available',
40
+ // questionID: 'teacher_not_available',
41
+ // nextSlide: 'slot_pick',
42
+ // }
43
+ // HYBRID_TEACHER:{
44
+ // id: 'hybrid_teacher',
45
+ // questionID: 'hybrid_teacher',
46
+ // nextSlide: 'trial_session_parent',
47
+ // },
48
+ CHILD_INFO: {
49
+ id: 'child_info',
50
+ questionID: 'child_info',
51
+ nextSlide: 'loader',// if ecna
52
+ // nextSlide:'teacher-unavailability' // if non-ecna + cred match
53
+ },
54
+ LOADER:{
55
+ id: 'loader',
56
+ questionID: 'loader',
57
+ nextSlide: 'hybrid_teacher',// if ecna
58
+ },
59
+ HYBRID_TEACHER:{
60
+ id: 'hybrid_teacher',
61
+ questionID: 'hybrid_teacher',
62
+ nextSlide:'date_time_slot_pick'
63
+ // nextSlide: 'trial_session_parent', // issue in ready to enroll
64
+ // nextSlide:'otp'
65
+ // nextSlide: 'class-confirmed',
66
+ },
67
+ TRIAL_SESSION_PARENT:{
68
+ id: 'trial_session_parent',
69
+ questionID: 'trial_session',
70
+ nextSlide: 'otp', // issue
71
+ // nextSlide: 'class-confirmed', // next slide
72
+ },
73
+ OTP:{
74
+ id: 'otp',
75
+ questionID: 'otp',
76
+ nextSlide: 'class-confirmed',
77
+ },
78
+ GET_IN_TOUCH:{
79
+ id: 'class-confirmed',
80
+ questionID: 'class-confirmed',
81
+ nextSlide: 'class-confirmed',
82
+ },
83
+ TRIAL_CONFIRMED:{
84
+ id: 'class-confirmed',
85
+ questionID: 'class-confirmed',
86
+ nextSlide: 'spreading_the_word',
87
+ },
88
+ TRIAL_SESSION:{
89
+ id: 'trial_session_slot',
90
+ questionID: 'trial_session_slot',
91
+ nextSlide: 'pick_slot',
92
+ },
93
+ PARENT_DETAILS:{
94
+ id: 'parent_details',
95
+ questionID: 'parent_details',
96
+ nextSlide: 'trial_session_parent',
97
+ },
98
+ PICK_SLOT:{
99
+ id: 'pick_slot',
100
+ questionID: 'pick_slot',
101
+ nextSlide: 'trial_session_parent',
102
+ },
103
+ DATE_TIME_SLOT_PICK:{
104
+ id: 'date_time_slot_pick',
105
+ questionID: 'date_time_slot_pick',
106
+ nextSlide: 'parent_details',
107
+ },
108
+ TEACHER_UNAVAILABILITY:{
109
+ id: 'teacher_unavailability',
110
+ questionID: 'teacher_unavailability',
111
+ nextSlide: 'date_time_slot_pick',
112
+ },
113
+ };
114
+
@@ -0,0 +1,32 @@
1
+ import { getCookie } from '../../cookie';
2
+ import { localStorageGet } from '../../local-storage';
3
+ import { SLIDE_TYPES, CUE_COUNTRY_CODE_KEY, LOCAL_STORAGE_KEYS } from '../../constants';
4
+
5
+ const K6Countries = ['AU', 'NZ']
6
+
7
+ export function checkGradeCountry(
8
+ country: string[],
9
+ currentGrade: string,
10
+ lessThanGrade: number,
11
+ ): boolean {
12
+ if (
13
+ country.includes(getCookie(CUE_COUNTRY_CODE_KEY)) &&
14
+ (parseInt(currentGrade, 10) <= lessThanGrade || currentGrade === 'KG')
15
+ ) {
16
+ return true;
17
+ }
18
+
19
+ return false;
20
+ }
21
+
22
+ export function isK4Student() {
23
+ return checkGradeCountry(K6Countries, localStorageGet(LOCAL_STORAGE_KEYS.STUDENT_GRADE), 4);
24
+ }
25
+
26
+ export function isK6Student() {
27
+ return checkGradeCountry(K6Countries, localStorageGet(LOCAL_STORAGE_KEYS.STUDENT_GRADE), 6);
28
+ }
29
+
30
+ export function getPerformanceQuestionAccordingToGrade() {
31
+ return isK4Student() ? SLIDE_TYPES.SCHOOL_PERFORMANCE_KG_4 : SLIDE_TYPES.SCHOOL_PERFORMANCE_5_12;
32
+ }
package/src/index.ts CHANGED
@@ -1,2 +1,7 @@
1
1
  export * from './cookie';
2
- export * from './growth-source';
2
+ export * from './constants';
3
+ export * from './local-storage';
4
+ export * from './e-cna';
5
+ export * from './date-time-helper';
6
+ export * from './country';
7
+ export * from './object';
@@ -0,0 +1,186 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ export const LOCAL_STORAGE_PRIMARY_KEY = 'CUEMATH_WEB';
3
+
4
+ export const checkLocalStorageSupport = () : boolean => {
5
+ try {
6
+ return 'localStorage' in window && window.localStorage !== null;
7
+ } catch (e) {
8
+ return false;
9
+ }
10
+ };
11
+
12
+ export const removeKeyFromObject = (obj: { [x: string]: any }, keyToRemove: string) => {
13
+ if (obj) {
14
+ delete obj[keyToRemove];
15
+ return obj
16
+ }
17
+
18
+ return null;
19
+ };
20
+
21
+ // Default expiry set to 24 hours
22
+ export const localStorageSet = (key: string | number, value: any, ttl = 86400000) => {
23
+ if (checkLocalStorageSupport()) {
24
+ try {
25
+ let dbData: any = window.localStorage.getItem(LOCAL_STORAGE_PRIMARY_KEY);
26
+ const now = new Date();
27
+
28
+ const item = {
29
+ value,
30
+ expiry: now.getTime() + ttl,
31
+ };
32
+
33
+ if (dbData) {
34
+ dbData = JSON.parse(dbData);
35
+ dbData[key] = item;
36
+ } else {
37
+ dbData = { [key]: item };
38
+ }
39
+
40
+ window.localStorage.setItem(LOCAL_STORAGE_PRIMARY_KEY, JSON.stringify(dbData));
41
+
42
+ return true;
43
+ } catch (e) {
44
+ return false;
45
+ } // case when localStorage space quota is exceeded
46
+ } else {
47
+ return false;
48
+ }
49
+ };
50
+
51
+ export const localStorageGet = (key: string) => {
52
+ if (checkLocalStorageSupport()) {
53
+ try {
54
+ const primaryLocalStorageValue = window.localStorage.getItem(
55
+ LOCAL_STORAGE_PRIMARY_KEY,
56
+ );
57
+ let dbData =
58
+ primaryLocalStorageValue != null
59
+ ? JSON.parse(primaryLocalStorageValue)
60
+ : primaryLocalStorageValue;
61
+ const requestedData = dbData[key];
62
+ const now = new Date();
63
+
64
+ if (now.getTime() > requestedData.expiry) {
65
+ dbData = removeKeyFromObject(dbData, key);
66
+ window.localStorage.setItem(LOCAL_STORAGE_PRIMARY_KEY, JSON.stringify(dbData));
67
+
68
+ return null;
69
+ }
70
+
71
+ return requestedData.value;
72
+ } catch (e) {
73
+ return null;
74
+ }
75
+ } else {
76
+ return null;
77
+ }
78
+ };
79
+
80
+ export const localStorageGetAll = () => {
81
+ if (checkLocalStorageSupport()) {
82
+ try {
83
+ const primaryLocalStorageValue = window.localStorage.getItem(
84
+ LOCAL_STORAGE_PRIMARY_KEY,
85
+ );
86
+
87
+ return primaryLocalStorageValue != null
88
+ ? JSON.parse(primaryLocalStorageValue)
89
+ : primaryLocalStorageValue;
90
+ } catch (e) {
91
+ return null;
92
+ }
93
+ } else {
94
+ return null;
95
+ }
96
+ };
97
+
98
+ export const localStorageRemove = (key: string) => {
99
+ if (checkLocalStorageSupport()) {
100
+ try {
101
+ const primaryLocalStorageValue = window.localStorage.getItem(
102
+ LOCAL_STORAGE_PRIMARY_KEY,
103
+ );
104
+ let dbData =
105
+ primaryLocalStorageValue != null
106
+ ? JSON.parse(primaryLocalStorageValue)
107
+ : primaryLocalStorageValue;
108
+
109
+ if (dbData[key]) {
110
+ dbData = removeKeyFromObject(dbData, key);
111
+ window.localStorage.setItem(LOCAL_STORAGE_PRIMARY_KEY, JSON.stringify(dbData));
112
+
113
+ return true;
114
+ }
115
+
116
+ return false;
117
+ } catch (e) {
118
+ return false;
119
+ }
120
+ } else {
121
+ return false;
122
+ }
123
+ };
124
+
125
+ export const localStorageRemoveAll = () => {
126
+ if (checkLocalStorageSupport()) {
127
+ try {
128
+ const primaryLocalStorageValue = window.localStorage.getItem(
129
+ LOCAL_STORAGE_PRIMARY_KEY,
130
+ );
131
+ const dbData =
132
+ primaryLocalStorageValue != null
133
+ ? JSON.parse(primaryLocalStorageValue)
134
+ : primaryLocalStorageValue;
135
+
136
+ if (dbData) {
137
+ window.localStorage.removeItem(LOCAL_STORAGE_PRIMARY_KEY);
138
+
139
+ return true;
140
+ }
141
+
142
+ return false;
143
+ } catch (e) {
144
+ return false;
145
+ }
146
+ } else {
147
+ return false;
148
+ }
149
+ };
150
+
151
+ export const removeExpiredKeysOnMount = () => {
152
+ if (checkLocalStorageSupport()) {
153
+ try {
154
+ const primaryLocalStorageValue = window.localStorage.getItem(
155
+ LOCAL_STORAGE_PRIMARY_KEY,
156
+ );
157
+ let dbData =
158
+ primaryLocalStorageValue != null
159
+ ? JSON.parse(primaryLocalStorageValue)
160
+ : primaryLocalStorageValue;
161
+ const now = new Date();
162
+
163
+ if (dbData) {
164
+ dbData = Object.keys(dbData).reduce((accumulator: any, key) => {
165
+ if (now.getTime() < dbData[key].expiry) {
166
+ accumulator[key] = dbData[key];
167
+ }
168
+
169
+ return accumulator;
170
+ }, {});
171
+ }
172
+
173
+ if (Object.keys(dbData).length) {
174
+ window.localStorage.setItem(LOCAL_STORAGE_PRIMARY_KEY, JSON.stringify(dbData));
175
+ } else {
176
+ localStorageRemoveAll();
177
+ }
178
+
179
+ return true;
180
+ } catch (e) {
181
+ return false;
182
+ }
183
+ } else {
184
+ return false;
185
+ }
186
+ };
@@ -0,0 +1,26 @@
1
+ export function isEmpty(obj: object): boolean {
2
+ return Object.keys(obj).length === 0;
3
+ }
4
+
5
+ // In this case both object have same key names Don't use to compare objects
6
+ export function isMapEqual(
7
+ map1: { [x: string]: any },
8
+ map2: { [x: string]: any },
9
+ ): boolean {
10
+ const map1Keys = Object.keys(map1);
11
+ const map2Keys = Object.keys(map2);
12
+
13
+ if (map1Keys.length !== map2Keys.length) {
14
+ return false;
15
+ }
16
+ for (let i = 0; i < map1Keys.length; i += 1) {
17
+ const key = map1Keys[i];
18
+
19
+ if (map1[key] !== map2[key]) {
20
+ return false;
21
+ }
22
+ }
23
+
24
+ return true;
25
+ }
26
+
@@ -1 +0,0 @@
1
- {}
@@ -1,172 +0,0 @@
1
- import type {
2
- SourceDetails,
3
- Platform,
4
- SignupFlow,
5
- UTMParams,
6
- Experiments,
7
- RevenueChannel,
8
- UTMParamsKeys,
9
- } from './types';
10
-
11
- import { createCookie, getCookie } from '../cookie';
12
-
13
- const SOURCE_DETAILS_COOKIE = 'source_details_v1';
14
- const UTM_PARAMS: UTMParamsKeys[] = [
15
- 'utm_source',
16
- 'utm_medium',
17
- 'utm_campaign',
18
- 'utm_term',
19
- ];
20
-
21
- export const readSourceCookie = () => {
22
- const sourceDetails = getCookie(SOURCE_DETAILS_COOKIE);
23
-
24
- return sourceDetails && JSON.parse(decodeURIComponent(sourceDetails));
25
- };
26
-
27
- const writeSourceCookie = (sourceDetails: SourceDetails) => {
28
- createCookie(SOURCE_DETAILS_COOKIE, JSON.stringify(sourceDetails), 365, true);
29
- };
30
-
31
- const updateSourceCookie = (sourceDetail: Partial<SourceDetails>) => {
32
- const sourceDetails: SourceDetails = readSourceCookie();
33
- const updatedDetails: SourceDetails = {
34
- ...sourceDetails,
35
- ...sourceDetail,
36
- };
37
-
38
- writeSourceCookie(updatedDetails);
39
- };
40
-
41
- const getRevenueChannel = (platform: Platform, utmParams?: UTMParams) => {
42
- let revenueChannel: RevenueChannel = 'UNKNOWN';
43
-
44
- if (platform === 'ASTRO' && utmParams) {
45
- const { utm_source: utmSource = '' } = utmParams;
46
-
47
- switch (true) {
48
- case /^affiliate-/.test(utmSource):
49
- revenueChannel = 'AFFILIATE';
50
- break;
51
- case /^offline-/.test(utmSource):
52
- revenueChannel = 'OFFLINE';
53
- break;
54
- case /^referral-/.test(utmSource):
55
- revenueChannel = 'REFERRAL';
56
- break;
57
- case /^performance-/.test(utmSource):
58
- default:
59
- revenueChannel = 'PERFORMANCE';
60
- }
61
- }
62
-
63
- if (platform === 'WEBSITE') {
64
- revenueChannel = 'ORGANIC';
65
- }
66
-
67
- return revenueChannel;
68
- };
69
-
70
- /*
71
- if Platform = website, then decide based on experiment key
72
- if Platform = Astro, decide logic once BAU is started
73
- if Platform = APP, decide logic
74
- if Platform = chatbot, decide based on chatbot experiment key
75
- */
76
- const getFlow = (platform: Platform, experiments?: Experiments) => {
77
- let flow: SignupFlow = 'REGULAR';
78
-
79
- if (platform === 'WEBSITE') {
80
- if (experiments) {
81
- const ecnaExp = Object.keys(experiments).find(
82
- experiment => experiment.indexOf('ecna') !== -1,
83
- );
84
-
85
- flow = ecnaExp && experiments[ecnaExp] === 'b' ? 'ECNA' : 'REGULAR';
86
- }
87
- }
88
-
89
- return flow;
90
- };
91
-
92
- const getUTMParams = () => {
93
- if (typeof window === undefined) return;
94
-
95
- const search = new URLSearchParams(window.location.search);
96
- const utmParams = UTM_PARAMS.reduce((acc: UTMParams, param) => {
97
- const utmParam = search.get(param) as string;
98
-
99
- if (utmParam) {
100
- acc[param] = utmParam;
101
- }
102
-
103
- return acc;
104
- }, {});
105
-
106
- return utmParams;
107
- };
108
-
109
- const getFirstPage = () => {
110
- if (typeof window === undefined) return '';
111
-
112
- return window.location.pathname;
113
- };
114
-
115
- /* TODO: Align Marketing Team on UTM source convention
116
- affiliate-<channel>
117
- performance-<channel>
118
- organic-<channel>
119
- offline-<channel>
120
- */
121
- const getChannel = (utmParams: UTMParams | undefined) => {
122
- // TODO: UTM source patter for FB, GOOGLE...
123
- if (!utmParams) return '';
124
-
125
- const { utm_source: utmSource = '' } = utmParams;
126
-
127
- return utmSource.split('-')[1];
128
- };
129
-
130
- /*
131
- Set Static Source Details of user on Visit of Platform
132
- */
133
- export const initSourceDetails = async ({
134
- platform,
135
- experiments,
136
- utmParams,
137
- flow,
138
- affiliateChannel,
139
- offlineChannel,
140
- organicChannel,
141
- performanceChannel,
142
- revenueChannel,
143
- }: SourceDetails) => {
144
- if (!readSourceCookie()) {
145
- const leadChannel = getChannel(utmParams);
146
-
147
- const sourceDetails: SourceDetails = {
148
- platform,
149
- experiments,
150
- utmParams: getUTMParams(),
151
- flow: flow || getFlow(platform, experiments),
152
- affiliateChannel: affiliateChannel || leadChannel,
153
- offlineChannel: offlineChannel || leadChannel,
154
- organicChannel: organicChannel || leadChannel,
155
- performanceChannel: performanceChannel || leadChannel,
156
- revenueChannel: revenueChannel || getRevenueChannel(platform, utmParams),
157
- firstPage: getFirstPage(),
158
- };
159
-
160
- writeSourceCookie(sourceDetails);
161
- }
162
- };
163
-
164
- // Last Page which user visited signup before
165
- export const setLastPage = async (pagePath: string) => {
166
- updateSourceCookie({ lastPage: pagePath });
167
- };
168
-
169
- // set Entry point where user clicked to Signup
170
- export const setFlowEntryPoint = async (flowEntry: string) => {
171
- updateSourceCookie({ flowEntry });
172
- };