@capillarytech/creatives-library 8.0.325 → 8.0.327-alpha.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 (72) hide show
  1. package/package.json +1 -1
  2. package/services/api.js +17 -0
  3. package/services/tests/api.test.js +85 -0
  4. package/utils/commonUtils.js +10 -0
  5. package/utils/tagValidations.js +2 -3
  6. package/utils/tests/commonUtil.test.js +169 -0
  7. package/utils/tests/tagValidations.test.js +1 -35
  8. package/v2Components/CapTagList/index.js +22 -14
  9. package/v2Components/CapTagList/style.scss +0 -48
  10. package/v2Components/CapTagListWithInput/index.js +0 -4
  11. package/v2Components/CapWhatsappCTA/index.js +0 -2
  12. package/v2Components/CommonTestAndPreview/AddTestCustomer.js +42 -0
  13. package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +155 -0
  14. package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +93 -0
  15. package/v2Components/CommonTestAndPreview/SendTestMessage.js +79 -51
  16. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +135 -36
  17. package/v2Components/CommonTestAndPreview/actions.js +10 -0
  18. package/v2Components/CommonTestAndPreview/constants.js +15 -1
  19. package/v2Components/CommonTestAndPreview/index.js +315 -15
  20. package/v2Components/CommonTestAndPreview/messages.js +106 -0
  21. package/v2Components/CommonTestAndPreview/reducer.js +10 -0
  22. package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +66 -0
  23. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +648 -0
  24. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +24 -0
  25. package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +174 -0
  26. package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +114 -0
  27. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +52 -0
  28. package/v2Components/CommonTestAndPreview/tests/constants.test.js +31 -1
  29. package/v2Components/CommonTestAndPreview/tests/index.test.js +36 -0
  30. package/v2Components/CommonTestAndPreview/tests/reducer.test.js +71 -0
  31. package/v2Components/CommonTestAndPreview/tests/selectors.test.js +17 -0
  32. package/v2Components/FormBuilder/index.js +0 -7
  33. package/v2Components/HtmlEditor/HTMLEditor.js +1 -6
  34. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -1
  35. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +2 -927
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +0 -3
  37. package/v2Containers/BeeEditor/index.js +0 -3
  38. package/v2Containers/CreativesContainer/SlideBoxContent.js +1 -28
  39. package/v2Containers/CreativesContainer/index.js +6 -10
  40. package/v2Containers/Email/index.js +0 -1
  41. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1 -7
  42. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +0 -3
  43. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +2 -20
  44. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +1 -16
  45. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +0 -3
  46. package/v2Containers/EmailWrapper/index.js +0 -4
  47. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -1
  48. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +0 -9
  49. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -19
  50. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -3
  51. package/v2Containers/InAppWrapper/index.js +0 -3
  52. package/v2Containers/MobilePush/Create/index.js +0 -2
  53. package/v2Containers/MobilePush/Edit/index.js +0 -2
  54. package/v2Containers/MobilepushWrapper/index.js +1 -3
  55. package/v2Containers/Rcs/index.js +1 -9
  56. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +1886 -1754
  57. package/v2Containers/Sms/Create/index.js +0 -2
  58. package/v2Containers/Sms/Edit/index.js +0 -2
  59. package/v2Containers/SmsTrai/Edit/index.js +0 -2
  60. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +351 -318
  61. package/v2Containers/SmsWrapper/index.js +0 -2
  62. package/v2Containers/TagList/index.js +2 -41
  63. package/v2Containers/TagList/messages.js +0 -4
  64. package/v2Containers/TagList/tests/TagList.test.js +20 -122
  65. package/v2Containers/TagList/tests/mockdata.js +0 -17
  66. package/v2Containers/Viber/index.js +0 -5
  67. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +2 -0
  68. package/v2Containers/WebPush/Create/index.js +1 -9
  69. package/v2Containers/Whatsapp/index.js +0 -5
  70. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +5586 -5232
  71. package/v2Containers/Zalo/index.js +0 -2
  72. package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +0 -63
@@ -5,9 +5,12 @@
5
5
  */
6
6
  @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
7
7
 
8
- /* All ant overrides scoped under wrapper to avoid affecting other modals. */
8
+ /* All ant overrides scoped under wrapper to avoid affecting other modals. */
9
9
  .common-test-preview-modal-wrap {
10
- z-index: 10000 !important;
10
+ z-index: 10000;
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
11
14
  }
12
15
 
13
16
  /* Lookup spinner overlay above test-customers dropdown. */
@@ -22,19 +25,23 @@
22
25
 
23
26
  /* When customer lookup is loading, dropdown renders inside .send-test-section; lower it so spinner is on top. */
24
27
  .common-test-preview-customer-loading .test-customers-tree-select-dropdown {
25
- z-index: 0 !important;
28
+ z-index: 0;
26
29
  }
27
30
 
28
31
  /* Customer creation modal content – avoid inline styles */
29
- .common-test-preview-modal {
30
- color: $CAP_G01 !important;
31
- .ant-modal-content {
32
- width: 28.5rem; /* 456px at 16px root */
33
- }
32
+ .common-test-preview-modal.common-test-preview-modal {
33
+ color: $CAP_G01;
34
+ width: 32.571em;
35
+ margin-left: auto;
36
+ margin-right: auto;
37
+ max-width: 32.571em;
38
+
34
39
  .ant-modal-footer {
35
40
  text-align: left;
36
- margin-left: 0.625rem; /* 10px at 16px root */
37
- margin-top: 0.9375rem; /* 15px at 16px root */
41
+ margin-left: 0.625rem;
42
+ /* 10px at 16px root */
43
+ margin-top: 0.9375rem;
44
+ /* 15px at 16px root */
38
45
  }
39
46
 
40
47
  .customer-creation-modal-row {
@@ -63,22 +70,72 @@
63
70
  font-weight: normal;
64
71
  }
65
72
 
73
+ /* Input text color and font to match standalone (lib mode can lose host styles) */
66
74
  .customer-creation-modal-input {
67
- width: 100%;
68
- color: $CAP_G01;
75
+ /* Sizes in em for 14px base: same px as .5rem 2.5rem 1.5rem .875rem at 16px (8px, 40px, 24px, 14px) */
76
+ .ant-input {
77
+ color: $CAP_G01;
78
+ font-size: $FONT_SIZE_M;
79
+ font-weight: normal;
80
+ padding: 0.571em;
81
+ /* 8px */
82
+ height: 2.857em;
83
+ /* 40px */
84
+ line-height: 1.714em;
85
+ /* 24px */
86
+ }
87
+
88
+ .ant-input:hover,
89
+ .ant-input:focus {
90
+ border: 1px solid $CAP_G01;
91
+ }
69
92
 
70
- &.has-error {
71
- color: $CAP_COLOR_03 !important;
72
- .ant-input {
73
- border-color: $CAP_COLOR_03 !important;
93
+ .ant-input::placeholder {
94
+ color: $CAP_G06;
95
+ }
96
+
97
+ /* Error state: single clean red border, no double line or focus ring */
98
+ &.has-input-error {
99
+ .ant-input-affix-wrapper {
100
+ border: 1px solid $CAP_COLOR_03;
101
+ border-radius: $CAP_SPACE_04;
102
+ }
103
+
104
+ .ant-input-affix-wrapper:hover,
105
+ .ant-input-affix-wrapper:focus,
106
+ .ant-input-affix-wrapper-focused {
107
+ border: 1px solid $CAP_COLOR_03;
108
+ }
109
+
110
+ .ant-input-affix-wrapper .ant-input {
111
+ border: none !important;
74
112
  }
75
113
  }
76
114
  }
77
115
 
116
+ /* Error message only – no extra border/line below the input */
78
117
  .customer-creation-modal-validation-error {
79
118
  color: $CAP_COLOR_03;
80
119
  font-size: $FONT_SIZE_S;
81
120
  margin-top: $CAP_SPACE_04;
121
+ border: none;
122
+ border-top: none;
123
+ box-shadow: none;
124
+
125
+ &::before,
126
+ &::after {
127
+ display: none;
128
+ content: none;
129
+ border: none;
130
+ }
131
+ }
132
+
133
+ /* Lookup loading: make Email and Mobile fields look disabled (wrapper-only) */
134
+ .customer-creation-modal--lookup-loading .customer-creation-modal-row--email .customer-creation-modal-input,
135
+ .customer-creation-modal--lookup-loading .customer-creation-modal-row--last .customer-creation-modal-input {
136
+ opacity: 0.65;
137
+ cursor: not-allowed;
138
+ background-color: $CAP_G09;
82
139
  }
83
140
 
84
141
  /* Existing customer modal content */
@@ -87,13 +144,17 @@
87
144
  margin-bottom: $CAP_SPACE_16;
88
145
  }
89
146
 
147
+ .ant-card.cap-card-v2 {
148
+ border: none
149
+ }
150
+
90
151
  .ant-card-body {
91
152
  padding: 1rem;
153
+ border-radius: $CAP_SPACE_08;
154
+ border: $CAP_SPACE_01 solid $CAP_G06;
92
155
  }
93
156
 
94
157
  &-card {
95
- border-radius: $CAP_SPACE_08;
96
- border: $CAP_SPACE_01 solid $CAP_G06;
97
158
  padding: 0;
98
159
  }
99
160
 
@@ -104,9 +165,11 @@
104
165
  }
105
166
 
106
167
  &-avatar {
107
- width: 3rem; /* 48px at 16px root */
168
+ width: 3rem;
169
+ /* 48px at 16px root */
108
170
  height: 3rem;
109
- border-radius: 1.25rem; /* 20px at 16px root */
171
+ border-radius: 1.25rem;
172
+ /* 20px at 16px root */
110
173
  background-color: $CAP_G07;
111
174
  display: flex;
112
175
  align-items: center;
@@ -150,15 +213,11 @@
150
213
  margin-right: 0.5rem;
151
214
  }
152
215
 
153
- /* CapSlideBox defaults to z-index 100; RCS SMS fallback slidebox + tag popovers use 10010–10020 — must stack above or close control is not clickable. */
154
- .cap-slide-box-v2.common-test-and-preview-slidebox {
216
+ .cap-slide-box-v2.common-test-and-preview-slidebox .cap-slide-box-v2-container {
155
217
  z-index: 10030;
156
218
  }
157
219
 
158
220
  .common-test-and-preview-slidebox {
159
- .common-test-preview-modal-wrap {
160
- z-index: 10003;
161
- }
162
221
 
163
222
  .ant-modal-mask,
164
223
  .ant-modal-wrap {
@@ -201,6 +260,7 @@
201
260
 
202
261
  .tag-input-field {
203
262
  width: 14.714rem;
263
+
204
264
  .input {
205
265
  height: $CAP_SPACE_40;
206
266
  }
@@ -213,12 +273,16 @@
213
273
 
214
274
  .left-panel {
215
275
  width: 40%;
276
+ min-width: 20rem;
277
+ /* Consistent width in campaigns/library mode so test customer dropdown matches creatives */
216
278
  padding-right: 1rem;
217
279
  border-right: $CAP_SPACE_01 solid $CAP_G12;
218
280
  overflow-y: auto;
281
+
219
282
  .panel-divider {
220
283
  margin: 0;
221
284
  }
285
+
222
286
  .no-tags-extracted-info-note {
223
287
  .note-text {
224
288
  white-space: unset;
@@ -267,6 +331,7 @@
267
331
  .values-missing-message {
268
332
  margin: $CAP_SPACE_16 0;
269
333
  }
334
+
270
335
  .editor-header {
271
336
  display: flex;
272
337
  justify-content: flex-end;
@@ -350,7 +415,7 @@
350
415
  align-items: center;
351
416
  min-height: $CAP_SPACE_20;
352
417
  padding-left: $CAP_SPACE_08;
353
-
418
+
354
419
  &:hover {
355
420
  background-color: #f5f5f5;
356
421
  }
@@ -416,6 +481,7 @@
416
481
  color: #bfbfbf;
417
482
  font-style: italic;
418
483
  }
484
+
419
485
  .ant-input {
420
486
  margin: $CAP_SPACE_06 0;
421
487
  height: $CAP_SPACE_36;
@@ -483,10 +549,11 @@
483
549
  justify-content: space-between;
484
550
  margin-bottom: $CAP_SPACE_16;
485
551
  }
552
+
486
553
  .editor-actions::before,
487
554
  .editor-actions::after {
488
- content: none;
489
- display: none;
555
+ content: none;
556
+ display: none;
490
557
  }
491
558
 
492
559
  .optional-tags-section {
@@ -495,9 +562,10 @@
495
562
  color: #666;
496
563
  }
497
564
 
498
- z-index: -1;
565
+ z-index: -1;
566
+
499
567
  .optional-tags-content {
500
- padding: $CAP_SPACE_16;
568
+ padding: $CAP_SPACE_16;
501
569
  background: #f5f5f5;
502
570
  border-radius: $CAP_SPACE_04;
503
571
  }
@@ -523,31 +591,40 @@
523
591
  margin-bottom: $CAP_SPACE_16;
524
592
  color: #666;
525
593
  }
594
+
526
595
  .ant-collapse-header {
527
596
  padding-left: 0;
528
597
  }
598
+
529
599
  .ant-collapse-content-box {
530
600
  padding-left: 0 !important;
531
601
  }
602
+
532
603
  .send-test-content {
533
604
  flex-direction: column;
534
605
  align-items: stretch;
535
606
  gap: 0;
536
607
  }
608
+
537
609
  .test-customers-tree-select {
538
610
  width: 100%;
611
+ min-width: 18rem;
612
+ /* Consistent dropdown width in campaigns and creatives */
539
613
  min-height: $CAP_SPACE_40;
540
614
  margin: $CAP_SPACE_12 0 $CAP_SPACE_08;
615
+
541
616
  .ant-select-selection,
542
617
  .ant-select-selector {
543
618
  min-height: $CAP_SPACE_40;
544
619
  height: auto !important;
545
620
  }
546
621
  }
622
+
547
623
  .send-test-content .ant-btn {
548
624
  margin-top: $CAP_SPACE_04;
549
625
  flex-shrink: 0;
550
626
  }
627
+
551
628
  .ant-select-selection__choice {
552
629
  background-color: $CAP_G08;
553
630
  border-radius: $CAP_SPACE_04;
@@ -557,8 +634,11 @@
557
634
 
558
635
  // Test customers TreeSelect dropdown: limit height and make scrollable (dropdown renders in portal)
559
636
  .test-customers-tree-select-dropdown {
560
- max-height: 20rem !important; /* 320px */
561
- overflow-y: auto !important;
637
+ min-width: 18rem;
638
+ max-height: 20rem;
639
+ /* 320px */
640
+ overflow-y: auto;
641
+
562
642
  .ant-select-tree-list-holder-inner {
563
643
  overflow: visible;
564
644
  }
@@ -566,8 +646,10 @@
566
646
 
567
647
  .test-customer-add-btn {
568
648
  width: 100%;
569
- background-color: transparent !important;
570
- color: $FONT_COLOR_05 !important;
649
+ &.ant-btn.cap-button-v2.flat-btn {
650
+ background-color: transparent;
651
+ color: $FONT_COLOR_05;
652
+ }
571
653
  white-space: normal;
572
654
  word-break: normal;
573
655
  overflow-wrap: break-word;
@@ -595,7 +677,7 @@
595
677
  padding-bottom: $CAP_SPACE_16;
596
678
  margin-bottom: $CAP_SPACE_16;
597
679
  }
598
-
680
+
599
681
  .right-panel {
600
682
  padding-left: 0;
601
683
  padding-top: $CAP_SPACE_16;
@@ -611,6 +693,7 @@
611
693
  .preview-divider {
612
694
  margin: 0;
613
695
  }
696
+
614
697
  .preview-header {
615
698
  display: flex;
616
699
  justify-content: space-between;
@@ -622,6 +705,7 @@
622
705
  font-size: $FONT_SIZE_M;
623
706
  color: #595959;
624
707
  gap: $CAP_SPACE_04;
708
+
625
709
  b {
626
710
  color: #262626;
627
711
  margin-left: $CAP_SPACE_04;
@@ -652,10 +736,12 @@
652
736
 
653
737
  .preview-body {
654
738
  border-radius: $CAP_SPACE_08;
655
- box-shadow: 0 $CAP_SPACE_04 $CAP_SPACE_12 rgba(0,0,0,0.1);
739
+ box-shadow: 0 $CAP_SPACE_04 $CAP_SPACE_12 rgba(0, 0, 0, 0.1);
740
+
656
741
  &.mobile {
657
742
  width: 26.786rem;
658
743
  margin: 0 auto;
744
+
659
745
  .browser-bar {
660
746
  background: $CAP_G08;
661
747
  }
@@ -671,13 +757,16 @@
671
757
  display: flex;
672
758
  gap: $CAP_SPACE_08;
673
759
  color: $CAP_G06;
760
+
674
761
  .refresh-icon {
675
762
  margin-top: $CAP_SPACE_04;
763
+
676
764
  svg path {
677
765
  fill: $CAP_G06;
678
766
  }
679
767
  }
680
768
  }
769
+
681
770
  .address-bar {
682
771
  flex-grow: 1;
683
772
  background: $CAP_WHITE;
@@ -687,13 +776,16 @@
687
776
  color: #595959;
688
777
  text-align: center;
689
778
  border: $CAP_SPACE_01 solid $CAP_G07;
779
+
690
780
  .address-bar-label {
691
781
  float: left;
692
782
  }
783
+
693
784
  .browser-address-bar-icon {
694
785
  float: right;
695
786
  }
696
787
  }
788
+
697
789
  .browser-actions {
698
790
  color: #8c8c8c;
699
791
  }
@@ -704,9 +796,11 @@
704
796
  align-items: center;
705
797
  padding: $CAP_SPACE_16;
706
798
  gap: $CAP_SPACE_16;
799
+
707
800
  .back-arrow {
708
801
  font-size: $CAP_SPACE_16;
709
802
  }
803
+
710
804
  .email-meta {
711
805
  margin-left: auto;
712
806
  display: flex;
@@ -714,6 +808,7 @@
714
808
  gap: $CAP_SPACE_08;
715
809
  font-size: $FONT_SIZE_S;
716
810
  color: #8c8c8c;
811
+
717
812
  .dots {
718
813
  width: $CAP_SPACE_06;
719
814
  height: $CAP_SPACE_06;
@@ -728,16 +823,19 @@
728
823
  align-items: center;
729
824
  padding: 0 $CAP_SPACE_16 $CAP_SPACE_16;
730
825
  gap: $CAP_SPACE_12;
826
+
731
827
  .sender-avatar {
732
828
  width: $CAP_SPACE_40;
733
829
  height: $CAP_SPACE_40;
734
830
  border-radius: 50%;
735
831
  background: $CAP_G12;
736
832
  }
833
+
737
834
  .sender-info {
738
835
  .sender-name {
739
836
  font-weight: 500;
740
837
  }
838
+
741
839
  .recipient-info {
742
840
  font-size: $FONT_SIZE_S;
743
841
  color: #8c8c8c;
@@ -748,6 +846,7 @@
748
846
  .email-content {
749
847
  border-top: $CAP_SPACE_01 solid $CAP_G12;
750
848
  padding: 0 $CAP_SPACE_16;
849
+
751
850
  iframe {
752
851
  border: none;
753
852
  }
@@ -20,6 +20,7 @@ import {
20
20
  CLEAR_PREVIEW_ERRORS,
21
21
  GET_SENDER_DETAILS_REQUESTED,
22
22
  GET_WECRM_ACCOUNTS_REQUESTED,
23
+ ADD_TEST_CUSTOMER,
23
24
  } from './constants';
24
25
 
25
26
  // ============================================
@@ -92,6 +93,15 @@ export const getTestGroupsRequested = () => ({
92
93
  type: GET_TEST_GROUPS_REQUESTED,
93
94
  });
94
95
 
96
+ /**
97
+ * Add a test customer to the list (e.g. after adding existing customer so tree shows name)
98
+ * @param {Object} customer - { userId, customerId, name, email, mobile }
99
+ */
100
+ export const addTestCustomer = (customer) => ({
101
+ type: ADD_TEST_CUSTOMER,
102
+ payload: { customer },
103
+ });
104
+
95
105
  /**
96
106
  * Create or update message meta configuration
97
107
  * @param {Object} payload - Message meta payload
@@ -33,6 +33,7 @@ export const SEND_TEST_MESSAGE_FAILURE = 'app/CommonTestAndPreview/SEND_TEST_MES
33
33
  export const GET_TEST_CUSTOMERS_REQUESTED = 'app/CommonTestAndPreview/GET_TEST_CUSTOMERS_REQUESTED';
34
34
  export const GET_TEST_CUSTOMERS_SUCCESS = 'app/CommonTestAndPreview/GET_TEST_CUSTOMERS_SUCCESS';
35
35
  export const GET_TEST_CUSTOMERS_FAILURE = 'app/CommonTestAndPreview/GET_TEST_CUSTOMERS_FAILURE';
36
+ export const ADD_TEST_CUSTOMER = 'app/CommonTestAndPreview/ADD_TEST_CUSTOMER';
36
37
 
37
38
  // Test Groups
38
39
  export const GET_TEST_GROUPS_REQUESTED = 'app/CommonTestAndPreview/GET_TEST_GROUPS_REQUESTED';
@@ -65,6 +66,12 @@ export const GET_WECRM_ACCOUNTS_REQUESTED = 'app/CommonTestAndPreview/GET_WECRM_
65
66
  export const GET_WECRM_ACCOUNTS_SUCCESS = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_SUCCESS';
66
67
  export const GET_WECRM_ACCOUNTS_FAILURE = 'app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_FAILURE';
67
68
 
69
+ // ============================================
70
+ // CUSTOMER MODAL TYPE (test customer addition)
71
+ // ============================================
72
+ export const CUSTOMER_MODAL_NEW = 'new';
73
+ export const CUSTOMER_MODAL_EXISTING = 'existing';
74
+
68
75
  // ============================================
69
76
  // CHANNEL CONSTANTS
70
77
  // ============================================
@@ -138,14 +145,21 @@ export const CLIENT_NAME_CREATIVES = 'CREATIVES';
138
145
  // Note: API uses "PUSH" instead of "MOBILEPUSH" for MobilePush channel
139
146
  export const API_CHANNEL_PUSH = 'PUSH';
140
147
 
148
+ // ============================================
149
+ // VALIDATION REGEX (shared with commonUtils for email/mobile validation)
150
+ // ============================================
151
+ export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
152
+ export const PHONE_REGEX = /^[1-9]\d{7,14}$/;
153
+
141
154
  // ============================================
142
155
  // IDENTIFIER TYPE CONSTANTS
143
156
  // ============================================
157
+ export const IDENTIFIER_TYPE_EMAIL = 'email';
144
158
  export const IDENTIFIER_TYPE_MOBILE = 'mobile';
145
159
  export const IDENTIFIER_TYPE_PHONE = 'phone';
146
160
 
147
161
  // Customer creation modal – input error state class suffix (used with customer-creation-modal-input)
148
- export const INPUT_HAS_ERROR_CLASS = ' has-error';
162
+ export const INPUT_HAS_ERROR_CLASS = ' has-input-error';
149
163
 
150
164
  // ============================================
151
165
  // CHANNEL NAME CONSTANTS (for CDN and other utilities)