@capillarytech/creatives-library 8.0.125 → 8.0.126

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 (40) hide show
  1. package/config/app.js +6 -0
  2. package/initialReducer.js +2 -0
  3. package/package.json +1 -1
  4. package/services/api.js +93 -0
  5. package/services/tests/api.test.js +191 -0
  6. package/v2Components/CustomerSearchSection/_customerSearch.scss +309 -0
  7. package/v2Components/CustomerSearchSection/constants.js +5 -0
  8. package/v2Components/CustomerSearchSection/index.js +362 -0
  9. package/v2Components/CustomerSearchSection/messages.js +20 -0
  10. package/v2Components/CustomerSearchSection/tests/utils.test.js +334 -0
  11. package/v2Components/CustomerSearchSection/utils.js +49 -0
  12. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +543 -0
  13. package/v2Components/TestAndPreviewSlidebox/actions.js +67 -0
  14. package/v2Components/TestAndPreviewSlidebox/constants.js +67 -0
  15. package/v2Components/TestAndPreviewSlidebox/index.js +771 -0
  16. package/v2Components/TestAndPreviewSlidebox/messages.js +147 -0
  17. package/v2Components/TestAndPreviewSlidebox/reducer.js +233 -0
  18. package/v2Components/TestAndPreviewSlidebox/sagas.js +258 -0
  19. package/v2Components/TestAndPreviewSlidebox/selectors.js +142 -0
  20. package/v2Components/TestAndPreviewSlidebox/tests/actions.test.js +80 -0
  21. package/v2Components/TestAndPreviewSlidebox/tests/reducer.test.js +367 -0
  22. package/v2Components/TestAndPreviewSlidebox/tests/saga.rtl.test.js +192 -0
  23. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +652 -0
  24. package/v2Components/TestAndPreviewSlidebox/tests/selector.test.js +182 -0
  25. package/v2Containers/CreativesContainer/SlideBoxContent.js +13 -1
  26. package/v2Containers/CreativesContainer/SlideBoxFooter.js +23 -2
  27. package/v2Containers/CreativesContainer/index.js +23 -2
  28. package/v2Containers/CreativesContainer/messages.js +4 -0
  29. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +21 -0
  30. package/v2Containers/Email/index.js +13 -1
  31. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +10 -0
  32. package/v2Containers/EmailWrapper/index.js +6 -0
  33. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  34. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  35. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  36. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  37. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +18 -0
  38. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  39. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -0
  40. package/v2Containers/Email/tests/index.test.js +0 -35
package/config/app.js CHANGED
@@ -7,6 +7,9 @@ const config = {
7
7
  campaigns_api_endpoint: '/iris/v2/campaigns',
8
8
  campaigns_api_org_endpoint: '/iris/v2/org/campaign',
9
9
  liquid_endpoint:'/iris/v2/template',
10
+ membercare_api_endpoint: '/member-care/api/v1',
11
+ iris_api_endpoint: '/iris/v2',
12
+ adiona_api_endpoint: '/adiona/api/v1',
10
13
  auth_endpoint: '/arya/api/v1/auth',
11
14
  arya_endpoint: '/arya/api/v1',
12
15
  login_url: '/auth/login',
@@ -27,6 +30,9 @@ const config = {
27
30
  login_url: '/auth/login',
28
31
  dashboard_url: '/sms',
29
32
  liquid_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/iris/v2/template',
33
+ membercare_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/member-care/api/v1',
34
+ iris_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/iris/v2',
35
+ adiona_api_endpoint: 'https://crm-nightly-new.cc.capillarytech.com/adiona/api/v1',
30
36
  dashboard_url_v2: '/v2',
31
37
  },
32
38
  testing: {
package/initialReducer.js CHANGED
@@ -14,6 +14,7 @@ import ftpReducer from 'v2Containers/FTP/reducer';
14
14
  import galleryReducer from './v2Containers/Assets/Gallery/reducer';
15
15
  import CapCollapsibleLeftNavigationReducer from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer';
16
16
  import { AIRA_REDUCER_DOMAIN, askAiraReducer } from '@capillarytech/cap-ui-library/CapAskAira';
17
+ import previewAndTestReducer from './v2Components/TestAndPreviewSlidebox/reducer';
17
18
 
18
19
  export const initialReducer = {
19
20
  language: languageProviderReducer,
@@ -31,4 +32,5 @@ export const initialReducer = {
31
32
  [AIRA_REDUCER_DOMAIN]: askAiraReducer,
32
33
  gallery: galleryReducer,
33
34
  navigationConfig: CapCollapsibleLeftNavigationReducer,
35
+ previewAndTest: previewAndTestReducer,
34
36
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.125",
4
+ "version": "8.0.126",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
package/services/api.js CHANGED
@@ -16,6 +16,9 @@ let EXPORT_API_ENDPOINT = config.development.exports_api_endpoint;
16
16
  let CAMPAIGNS_API_ENDPOINT = config.development.campaigns_api_endpoint;
17
17
  let CAMPAIGNS_API_ORG_ENDPOINT = config.development.campaigns_api_org_endpoint;
18
18
  let LIQUID_API_ENDPOINT = config.development.liquid_endpoint;
19
+ let MEMBERCARE_API_ENDPOINT = config.development.membercare_api_endpoint;
20
+ let IRIS_API_ENDPOINT = config.development.iris_api_endpoint;
21
+ let ADIONA_API_ENDPOINT = config.development.adiona_api_endpoint;
19
22
 
20
23
  let API_AUTH_ENDPOINT = config.development.auth_endpoint;
21
24
  let ARYA_ENDPOINT = config.development.arya_endpoint;
@@ -29,6 +32,9 @@ if (process.env.NODE_ENV === 'production') {
29
32
  SUBSCRIPTION_API_ENDPOINT = config.production.subscription_api_endpoint;
30
33
  EXPORT_API_ENDPOINT = config.production.exports_api_endpoint;
31
34
  LIQUID_API_ENDPOINT = config.production.liquid_endpoint;
35
+ MEMBERCARE_API_ENDPOINT = config.production.membercare_api_endpoint;
36
+ IRIS_API_ENDPOINT = config.production.iris_api_endpoint;
37
+ ADIONA_API_ENDPOINT = config.production.adiona_api_endpoint;
32
38
  }
33
39
  let requestCallerName = '';
34
40
  const isProd = process.env.NODE_ENV === 'production';
@@ -172,6 +178,46 @@ function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeader
172
178
  return requestObj;
173
179
  }
174
180
 
181
+ function get_LOYALTY_API_CallObject(method, body, notStringify) {
182
+ const token = loadItem('token');
183
+ const orgID = loadItem('orgID');
184
+ const user = loadItem('user');
185
+ const headers = {};
186
+
187
+ if (!notStringify) {
188
+ headers['Content-Type'] = 'application/json';
189
+ }
190
+
191
+ if (user && user.refID) {
192
+ headers['X-CAP-REMOTE-USER'] = user.refID;
193
+ }
194
+
195
+ if (process.env.NODE_ENV !== 'production' && orgID !== undefined) {
196
+ headers['X-CAP-API-AUTH-ORG-ID'] = orgID;
197
+ }
198
+
199
+ if (token !== undefined) {
200
+ headers.Authorization = `Bearer ${token}`;
201
+ }
202
+ const requestObj = {
203
+ method,
204
+ mode: 'cors',
205
+ headers: new Headers(headers),
206
+ };
207
+
208
+ if (process.env.NODE_ENV === 'production') {
209
+ requestObj.credentials = 'same-origin';
210
+ }
211
+
212
+ if (body && !notStringify) {
213
+ requestObj.body = JSON.stringify(body);
214
+ } else {
215
+ requestObj.body = body;
216
+ }
217
+
218
+ return requestObj;
219
+ }
220
+
175
221
  // Authentication
176
222
  export const authorize = (user) => {
177
223
  const body = {
@@ -584,4 +630,51 @@ export const createCentralCommsMetaId = (payload, metaType = TRANSACTION) => {
584
630
  return request(url, getAPICallObject('POST', payload, false, false, false, true));
585
631
  };
586
632
 
633
+ // Customer Search APIs for Email Test & Preview Feature
634
+ export const searchCustomers = ({ query }) => {
635
+ const url = `${MEMBERCARE_API_ENDPOINT}/customers/search?q=${encodeURIComponent(query)}&limit=10`;
636
+ return request(url, get_LOYALTY_API_CallObject('GET'));
637
+ };
638
+
639
+ export const extractTagsWithMetaData = (payload) => {
640
+ const url = `${LIQUID_API_ENDPOINT}/extractTagsWithMetaData`;
641
+ return request(url, getAPICallObject('POST', payload, false, true));
642
+ };
643
+
644
+ export const updateEmailPreview = (payload) => {
645
+ const url = `${LIQUID_API_ENDPOINT}/preview`;
646
+ return request(url, getAPICallObject('POST', payload, false, true));
647
+ };
648
+
649
+ export const sendTestMessage = (payload) => {
650
+ const url = `${LIQUID_API_ENDPOINT}/sendTestMessage`;
651
+ return request(url, getAPICallObject('POST', payload, false, true));
652
+ };
653
+
654
+ export const fetchTestCustomers = () => {
655
+ const url = `${IRIS_API_ENDPOINT}/userGroup/default`;
656
+ return request(url, getAPICallObject('GET', null, false, true));
657
+ };
658
+
659
+ export const fetchTestGroups = () => {
660
+ const url = `${IRIS_API_ENDPOINT}/userGroup?isDefault=false`;
661
+ return request(url, getAPICallObject('GET', null, false, true));
662
+ };
663
+
664
+ export const getBulkCustomerDetails = (userIds) => {
665
+ const user = loadItem('user');
666
+ const url = `${ADIONA_API_ENDPOINT}/journeys/getBulkCustomer?source=ALL&userValue=${user?.loginName}`;
667
+ return request(url, get_LOYALTY_API_CallObject('POST', userIds));
668
+ };
669
+
670
+ export const createTestMessageMeta = (payload) => {
671
+ const url = `${LIQUID_API_ENDPOINT}/TEST/createMessageMeta`;
672
+ return request(url, getAPICallObject('POST', payload, false, true));
673
+ };
674
+
675
+ export const updateTestMessageMeta = (payload) => {
676
+ const url = `${LIQUID_API_ENDPOINT}/TEST/${payload.messageMetaConfigId}/updateMessageMeta`;
677
+ return request(url, getAPICallObject('POST', payload?.data, false, true));
678
+ };
679
+
587
680
  export {request, getAPICallObject};
@@ -14,6 +14,15 @@ import {
14
14
  fetchSchemaForEntity,
15
15
  getDefaultBeeTemplates,
16
16
  getEdmTemplates,
17
+ searchCustomers,
18
+ extractTagsWithMetaData,
19
+ updateEmailPreview,
20
+ sendTestMessage,
21
+ fetchTestCustomers,
22
+ fetchTestGroups,
23
+ getBulkCustomerDetails,
24
+ createTestMessageMeta,
25
+ updateTestMessageMeta,
17
26
  } from '../api';
18
27
  import { mockData } from './mockData';
19
28
  import getSchema from '../getSchema';
@@ -613,3 +622,185 @@ describe('Email Template APIs', () => {
613
622
  sharedTests(getDefaultBeeTemplates, 'getDefaultBeeTemplates');
614
623
  });
615
624
  });
625
+
626
+ describe('searchCustomers', () => {
627
+ it('should return correct response', async () => {
628
+ global.fetch.mockReturnValue(Promise.resolve({
629
+ status: 200,
630
+ json: () => Promise.resolve({
631
+ status: 200,
632
+ response: 'test',
633
+ }),
634
+ }));
635
+ const result = await searchCustomers({ query: 'test' });
636
+ expect(result).toEqual({
637
+ status: 200,
638
+ response: 'test',
639
+ });
640
+ });
641
+ it('should handle fetch failure', async () => {
642
+ global.fetch.mockRejectedValue({ error: 'Network error' });
643
+ const result = await searchCustomers({ query: 'test' });
644
+ expect(result).toEqual({
645
+ error: 'Network error',
646
+ });
647
+ });
648
+ });
649
+ describe('extractTagsWithMetaData', () => {
650
+ it('should return correct response', async () => {
651
+ global.fetch.mockReturnValue(Promise.resolve({
652
+ status: 200,
653
+ json: () => Promise.resolve({
654
+ status: 200,
655
+ response: 'test',
656
+ }),
657
+ }));
658
+ const result = await extractTagsWithMetaData({ query: 'test' });
659
+ expect(result).toEqual({
660
+ status: 200,
661
+ response: 'test',
662
+ });
663
+ });
664
+ it('should handle fetch failure', async () => {
665
+ global.fetch.mockRejectedValue({ error: 'Network error' });
666
+ const result = await extractTagsWithMetaData({ query: 'test' });
667
+ expect(result).toEqual({
668
+ error: 'Network error',
669
+ });
670
+ });
671
+ });
672
+
673
+ describe('updateEmailPreview', () => {
674
+ it('should return correct response', async () => {
675
+ global.fetch.mockReturnValue(Promise.resolve({
676
+ status: 200,
677
+ json: () => Promise.resolve({
678
+ status: 200,
679
+ response: 'test',
680
+ }),
681
+ }));
682
+ const result = await updateEmailPreview({ query: 'test' });
683
+ expect(result).toEqual({
684
+ status: 200,
685
+ response: 'test',
686
+ });
687
+ });
688
+ it('should handle fetch failure', async () => {
689
+ global.fetch.mockRejectedValue({ error: 'Network error' });
690
+ const result = await updateEmailPreview({ query: 'test' });
691
+ expect(result).toEqual({
692
+ error: 'Network error',
693
+ });
694
+ });
695
+ });
696
+
697
+ describe('sendTestMessage', () => {
698
+ it('should return correct response', async () => {
699
+ global.fetch.mockReturnValue(Promise.resolve({
700
+ status: 200,
701
+ json: () => Promise.resolve({
702
+ status: 200,
703
+ response: 'test',
704
+ }),
705
+ }));
706
+ const result = await sendTestMessage({ query: 'test' });
707
+ expect(result).toEqual({
708
+ status: 200,
709
+ response: 'test',
710
+ });
711
+ });
712
+ });
713
+ describe('fetchTestCustomers', () => {
714
+ it('should return correct response', async () => {
715
+ global.fetch.mockReturnValue(Promise.resolve({
716
+ status: 200,
717
+ json: () => Promise.resolve({
718
+ status: 200,
719
+ response: 'test',
720
+ }),
721
+ }));
722
+ const result = await fetchTestCustomers({ query: 'test' });
723
+ expect(result).toEqual({
724
+ status: 200,
725
+ response: 'test',
726
+ });
727
+ });
728
+ it('should handle fetch failure', async () => {
729
+ global.fetch.mockRejectedValue({ error: 'Network error' });
730
+ const result = await fetchTestCustomers({ query: 'test' });
731
+ expect(result).toEqual({
732
+ error: 'Network error',
733
+ });
734
+ });
735
+ });
736
+ describe('fetchTestGroups', () => {
737
+ it('should return correct response', async () => {
738
+ global.fetch.mockReturnValue(Promise.resolve({
739
+ status: 200,
740
+ json: () => Promise.resolve({
741
+ status: 200,
742
+ response: 'test',
743
+ }),
744
+ }));
745
+ const result = await fetchTestGroups({ query: 'test' });
746
+ expect(result).toEqual({
747
+ status: 200,
748
+ response: 'test',
749
+ });
750
+ });
751
+ });
752
+ describe('getBulkCustomerDetails', () => {
753
+ it('should return correct response', async () => {
754
+ global.fetch.mockReturnValue(Promise.resolve({
755
+ status: 200,
756
+ json: () => Promise.resolve({
757
+ status: 200,
758
+ response: 'test',
759
+ }),
760
+ }));
761
+ const result = await getBulkCustomerDetails({ query: 'test' });
762
+ expect(result).toEqual({
763
+ status: 200,
764
+ response: 'test',
765
+ });
766
+ });
767
+ it('should handle fetch failure', async () => {
768
+ global.fetch.mockRejectedValue({ error: 'Network error' });
769
+ const result = await getBulkCustomerDetails({ query: 'test' });
770
+ expect(result).toEqual({
771
+ error: 'Network error',
772
+ });
773
+ });
774
+ });
775
+ describe('createTestMessageMeta', () => {
776
+ it('should return correct response', async () => {
777
+ global.fetch.mockReturnValue(Promise.resolve({
778
+ status: 200,
779
+ json: () => Promise.resolve({
780
+ status: 200,
781
+ response: 'test',
782
+ }),
783
+ }));
784
+ const result = await createTestMessageMeta({ query: 'test' });
785
+ expect(result).toEqual({
786
+ status: 200,
787
+ response: 'test',
788
+ });
789
+ });
790
+ });
791
+ describe('updateTestMessageMeta', () => {
792
+ it('should return correct response', async () => {
793
+ global.fetch.mockReturnValue(Promise.resolve({
794
+ status: 200,
795
+ json: () => Promise.resolve({
796
+ status: 200,
797
+ response: 'test',
798
+ }),
799
+ }));
800
+ const result = await updateTestMessageMeta({ query: 'test' });
801
+ expect(result).toEqual({
802
+ status: 200,
803
+ response: 'test',
804
+ });
805
+ });
806
+ });
@@ -0,0 +1,309 @@
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
+
3
+ .customer-search-section {
4
+ margin-top: $CAP_SPACE_08;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: $CAP_SPACE_04;
8
+ padding: 0;
9
+ position: relative;
10
+
11
+ .customer-search-label {
12
+ font-weight: bold;
13
+ margin-bottom: $CAP_SPACE_04;
14
+ font-size: $CAP_SPACE_16;
15
+ }
16
+
17
+ .search-container {
18
+ position: relative;
19
+ }
20
+
21
+ .search-dropdown-container {
22
+ position: absolute;
23
+ width: 100%;
24
+ z-index: 1000;
25
+ }
26
+
27
+ .search-result-card {
28
+ width: 100%;
29
+ margin: 0;
30
+ box-shadow: 0 $CAP_SPACE_04 $CAP_SPACE_12 rgba(0, 0, 0, 0.15);
31
+ border-radius: $CAP_SPACE_08;
32
+ border: 1px solid #d9d9d9;
33
+
34
+ .ant-card-body {
35
+ padding: $CAP_SPACE_08;
36
+ }
37
+ }
38
+
39
+ .link-result {
40
+ .ant-row.ant-row-flex {
41
+ padding: $CAP_SPACE_08 $CAP_SPACE_12;
42
+ border-radius: $CAP_SPACE_06;
43
+
44
+ &:hover {
45
+ background-color: #f0f0f0;
46
+ }
47
+ }
48
+ }
49
+
50
+ .customer-common-profile {
51
+ width: $CAP_SPACE_40;
52
+ height: $CAP_SPACE_40;
53
+ border-radius: 50%;
54
+ background-color: #E7D0FB;
55
+ color: $CAP_PURPLE;
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ font-weight: bold;
60
+ font-size: $CAP_SPACE_16;
61
+ }
62
+
63
+ .search-text {
64
+ &.ant-typography {
65
+ font-weight: bold;
66
+ color: #262626;
67
+ margin-bottom: 0;
68
+ }
69
+ }
70
+
71
+
72
+ .identifiers-text {
73
+ margin-top: -0.6rem;
74
+ color: #8c8c8c;
75
+ .highlight-background-color {
76
+ background-color: transparent;
77
+ font-weight: bold;
78
+ }
79
+ }
80
+ .identifier-desc {
81
+ margin-top: 0.6rem;
82
+ }
83
+
84
+ .link-result-divider {
85
+ margin: 0 $CAP_SPACE_12;
86
+ }
87
+
88
+ .selected-customer-view {
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: space-between;
92
+ padding: $CAP_SPACE_04 $CAP_SPACE_12;
93
+ border: 1px solid #d9d9d9;
94
+ border-radius: $CAP_SPACE_06;
95
+ background-color: $CAP_WHITE;
96
+ height: $CAP_SPACE_40;
97
+ cursor: default;
98
+
99
+ .customer-common-profile {
100
+ width: $CAP_SPACE_24;
101
+ height: $CAP_SPACE_24;
102
+ font-size: $CAP_SPACE_12;
103
+ }
104
+
105
+ .search-text, .identifiers-text {
106
+ margin-bottom: 0;
107
+ }
108
+ .multiple-identifiers {
109
+ margin: 0.25rem 0;
110
+ }
111
+
112
+ .clear-icon {
113
+ cursor: pointer;
114
+ color: #8c8c8c;
115
+ }
116
+ }
117
+
118
+ .search-input-container {
119
+ position: relative;
120
+ .search-error {
121
+ margin-top: $CAP_SPACE_08;
122
+ }
123
+ }
124
+
125
+ .validation-card {
126
+ min-width: 100%;
127
+ max-width: 100%;
128
+ margin: 0;
129
+ box-shadow: 0 $CAP_SPACE_04 $CAP_SPACE_08 -2px rgba(9, 30, 66, 0.25),
130
+ 0 0 1px 0 rgba(9, 30, 66, 0.31);
131
+ border-top-left-radius: unset;
132
+ border-top-right-radius: unset;
133
+ border-top-color: transparent;
134
+ .ant-card-body {
135
+ padding: $CAP_SPACE_12 $CAP_SPACE_20;
136
+ }
137
+ }
138
+
139
+ .search-dropdown {
140
+ position: absolute;
141
+ top: 100%;
142
+ left: 0;
143
+ right: 0;
144
+ background: #fff;
145
+ border: 1px solid #d9d9d9;
146
+ border-top: none;
147
+ border-radius: 0 0 $CAP_SPACE_06 $CAP_SPACE_06;
148
+ box-shadow: 0 $CAP_SPACE_02 $CAP_SPACE_08 rgba(0, 0, 0, 0.1);
149
+ max-height: 200px;
150
+ overflow-y: auto;
151
+ z-index: 1050;
152
+
153
+ &.no-results {
154
+ .no-results-message {
155
+ display: flex;
156
+ align-items: center;
157
+ gap: $CAP_SPACE_08;
158
+ padding: $CAP_SPACE_16;
159
+ color: #8c8c8c;
160
+ font-size: 1rem;
161
+
162
+ .cap-icon {
163
+ color: #d9d9d9;
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ .customer-result-item {
170
+ display: flex;
171
+ align-items: center;
172
+ gap: $CAP_SPACE_12;
173
+ padding: $CAP_SPACE_12 $CAP_SPACE_16;
174
+ cursor: pointer;
175
+ border-bottom: 1px solid #f0f0f0;
176
+ transition: background-color 0.2s ease;
177
+
178
+ &:hover {
179
+ background-color: #f5f5f5;
180
+ }
181
+
182
+ &:last-child {
183
+ border-bottom: none;
184
+ }
185
+
186
+ .customer-avatar {
187
+ flex-shrink: 0;
188
+ }
189
+
190
+ .customer-details {
191
+ flex: 1;
192
+ min-width: 0;
193
+
194
+ .customer-name {
195
+ font-weight: 500;
196
+ font-size: 1rem;
197
+ color: #262626;
198
+ margin-bottom: 2px;
199
+ }
200
+
201
+ .customer-email {
202
+ font-size: $CAP_SPACE_12;
203
+ color: #8c8c8c;
204
+ margin-bottom: 2px;
205
+ }
206
+
207
+ .customer-phone {
208
+ font-size: $CAP_SPACE_12;
209
+ color: #8c8c8c;
210
+ }
211
+ }
212
+
213
+ .customer-id {
214
+ flex-shrink: 0;
215
+ font-size: $CAP_SPACE_12;
216
+ color: #8c8c8c;
217
+ font-weight: 500;
218
+ }
219
+ }
220
+
221
+ .selected-customer {
222
+ display: flex;
223
+ flex-direction: column;
224
+ gap: $CAP_SPACE_16;
225
+ padding: $CAP_SPACE_16;
226
+ background: #f8f9fa;
227
+ border: 1px solid #e8e8e8;
228
+ border-radius: $CAP_SPACE_06;
229
+
230
+ .selected-customer-info {
231
+ display: flex;
232
+ align-items: center;
233
+ gap: $CAP_SPACE_12;
234
+
235
+ .customer-details {
236
+ flex: 1;
237
+
238
+ .customer-name {
239
+ font-weight: 500;
240
+ font-size: 1rem;
241
+ color: #262626;
242
+ margin-bottom: $CAP_SPACE_04;
243
+ }
244
+
245
+ .customer-email {
246
+ font-size: $CAP_SPACE_12;
247
+ color: #8c8c8c;
248
+ margin-bottom: $CAP_SPACE_04;
249
+ }
250
+
251
+ .customer-id {
252
+ font-size: $CAP_SPACE_12;
253
+ color: #8c8c8c;
254
+ font-weight: 500;
255
+ }
256
+ }
257
+ }
258
+
259
+ .selected-customer-actions {
260
+ display: flex;
261
+ justify-content: flex-end;
262
+ align-items: center;
263
+ }
264
+
265
+ .tag-extraction-success {
266
+ .extraction-summary {
267
+ display: flex;
268
+ align-items: center;
269
+ gap: $CAP_SPACE_08;
270
+ margin-bottom: $CAP_SPACE_12;
271
+ font-size: 1rem;
272
+ font-weight: 500;
273
+ color: #52c41a;
274
+ }
275
+
276
+ .required-tags,
277
+ .optional-tags {
278
+ margin-bottom: $CAP_SPACE_12;
279
+
280
+ .tag-category {
281
+ display: flex;
282
+ align-items: center;
283
+ gap: $CAP_SPACE_08;
284
+ margin-bottom: $CAP_SPACE_08;
285
+ font-size: 13px;
286
+ font-weight: 500;
287
+ }
288
+
289
+ .tag-list {
290
+ display: flex;
291
+ flex-wrap: wrap;
292
+ gap: $CAP_SPACE_06;
293
+ }
294
+ }
295
+
296
+ .required-tags .tag-category {
297
+ color: #fa8c16;
298
+ }
299
+
300
+ .optional-tags .tag-category {
301
+ color: #52c41a;
302
+ }
303
+
304
+ .api-warnings {
305
+ margin-top: $CAP_SPACE_08;
306
+ }
307
+ }
308
+ }
309
+ }
@@ -0,0 +1,5 @@
1
+ export const FIRSTNAME = 'firstname';
2
+ export const LASTNAME = 'lastname';
3
+ export const INSTORE = 'instore';
4
+ export const NA = 'N/A';
5
+ export const MINIMUM_IDENTIFIER_LENGTH = 1;