@product7/product7-js 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -452,9 +452,9 @@
452
452
  content: feedbackData.content,
453
453
  attachments: feedbackData.attachments || [],
454
454
  ...(contact?.contactId && {
455
- contact_id: contact.contactId,
455
+ contact_id: contact.contactId,
456
456
  contact_email: contact.contactEmail,
457
- contact_name: contact.contactName,
457
+ contact_name: contact.contactName,
458
458
  }),
459
459
  };
460
460
 
@@ -972,9 +972,9 @@
972
972
  }),
973
973
  ...(respondent.email && { email: respondent.email }),
974
974
  ...(contact?.contactId && {
975
- contact_id: contact.contactId,
975
+ contact_id: contact.contactId,
976
976
  contact_email: contact.contactEmail,
977
- contact_name: contact.contactName,
977
+ contact_name: contact.contactName,
978
978
  }),
979
979
  };
980
980
 
@@ -5706,7 +5706,7 @@
5706
5706
  background: var(--color-white);
5707
5707
  border: 1px solid var(--color-neutral-200);
5708
5708
  border-radius: var(--radius-xl);
5709
- box-shadow: var(--shadow-lg);
5709
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
5710
5710
  padding: var(--spacing-6);
5711
5711
  min-width: 320px;
5712
5712
  max-width: 400px;
@@ -5717,11 +5717,10 @@
5717
5717
  }
5718
5718
 
5719
5719
  /* ========================================
5720
- DARK THEME — scoped variable overrides
5720
+ DARK THEME
5721
5721
  ======================================== */
5722
5722
 
5723
5723
  .feedback-survey-theme-dark {
5724
- /* Aligned with messenger dark theme */
5725
5724
  --color-white: #0f1317;
5726
5725
  --color-background: #0f1317;
5727
5726
  --color-surface: #1a1e24;
@@ -5736,7 +5735,6 @@
5736
5735
  --color-text-primary: #e8e8e8;
5737
5736
  --color-text-secondary: #999999;
5738
5737
  --color-text-tertiary: #666666;
5739
- /* Survey-specific tokens */
5740
5738
  --color-primary-light: rgba(21, 94, 239, 0.18);
5741
5739
  --color-primary-border: rgba(21, 94, 239, 0.4);
5742
5740
  --color-error-light: rgba(239, 68, 68, 0.15);
@@ -5766,7 +5764,6 @@
5766
5764
  transform: translate(-50%, -50%) scale(0.97);
5767
5765
  }
5768
5766
 
5769
-
5770
5767
  /* ========================================
5771
5768
  CLOSE BUTTON
5772
5769
  ======================================== */
@@ -5858,7 +5855,7 @@
5858
5855
  }
5859
5856
 
5860
5857
  /* ========================================
5861
- NPS
5858
+ NPS — individual colored buttons
5862
5859
  ======================================== */
5863
5860
 
5864
5861
  .feedback-survey-nps {
@@ -5871,40 +5868,51 @@
5871
5868
  flex: 1;
5872
5869
  height: 40px;
5873
5870
  min-height: unset;
5874
- border: 1px solid var(--color-border);
5875
- border-radius: var(--radius-md);
5876
- background: var(--color-surface);
5871
+ border-radius: 6px;
5877
5872
  cursor: pointer;
5878
5873
  font-size: var(--font-size-sm);
5879
5874
  font-weight: var(--font-weight-medium);
5880
- color: var(--color-text-primary);
5881
- transition: all var(--transition-fast);
5875
+ color: #ffffff;
5876
+ border: 1px solid transparent;
5877
+ transition: filter var(--transition-fast), transform var(--transition-fast);
5882
5878
  font-family: inherit;
5883
5879
  }
5884
5880
 
5885
5881
  .feedback-survey-nps-btn:hover {
5886
- background: var(--color-primary-light);
5887
- border-color: var(--color-primary-border);
5888
- color: var(--color-primary);
5882
+ filter: brightness(1.12);
5889
5883
  }
5890
5884
 
5891
5885
  .feedback-survey-nps-btn.selected {
5892
- background: var(--color-primary-light);
5893
- border-color: var(--color-primary);
5894
- color: var(--color-primary-active);
5895
- transform: scale(1.06);
5896
- z-index: 1;
5897
- position: relative;
5886
+ filter: brightness(0.82);
5887
+ box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.25);
5888
+ }
5889
+
5890
+ .feedback-survey-nps-btn:active {
5891
+ transform: translateY(1px);
5892
+ transition-duration: 100ms;
5898
5893
  }
5899
5894
 
5895
+ /* NPS score colors */
5896
+ .feedback-survey-nps-score-0 { background: #dc2626; border-color: #dc2626; }
5897
+ .feedback-survey-nps-score-1 { background: #ef4444; border-color: #ef4444; }
5898
+ .feedback-survey-nps-score-2 { background: #f97316; border-color: #f97316; }
5899
+ .feedback-survey-nps-score-3 { background: #fb923c; border-color: #fb923c; }
5900
+ .feedback-survey-nps-score-4 { background: #fdba74; border-color: #fdba74; }
5901
+ .feedback-survey-nps-score-5 { background: #fbbf24; border-color: #fbbf24; }
5902
+ .feedback-survey-nps-score-6 { background: #fde047; border-color: #fde047; color: #171717; }
5903
+ .feedback-survey-nps-score-7 { background: #e5e7eb; border-color: #e5e7eb; color: #374151; }
5904
+ .feedback-survey-nps-score-8 { background: #e5e7eb; border-color: #e5e7eb; color: #374151; }
5905
+ .feedback-survey-nps-score-9 { background: #4ade80; border-color: #4ade80; }
5906
+ .feedback-survey-nps-score-10 { background: #16a34a; border-color: #16a34a; }
5907
+
5900
5908
  /* ========================================
5901
- CSAT
5909
+ CSAT — emoji row
5902
5910
  ======================================== */
5903
5911
 
5904
5912
  .feedback-survey-csat {
5905
5913
  display: flex;
5906
- justify-content: center;
5907
- gap: var(--spacing-4);
5914
+ justify-content: space-between;
5915
+ gap: var(--spacing-3);
5908
5916
  padding: var(--spacing-2) 0;
5909
5917
  }
5910
5918
 
@@ -5914,7 +5922,7 @@
5914
5922
  cursor: pointer;
5915
5923
  font-size: 32px;
5916
5924
  transition: transform var(--transition-fast), opacity var(--transition-fast);
5917
- padding: var(--spacing-2);
5925
+ padding: var(--spacing-2) var(--spacing-1);
5918
5926
  min-width: 44px;
5919
5927
  min-height: 44px;
5920
5928
  display: flex;
@@ -5937,147 +5945,24 @@
5937
5945
  opacity: 0.3;
5938
5946
  }
5939
5947
 
5940
- /* ========================================
5941
- CES SEGMENTED (short scale)
5942
- ======================================== */
5943
-
5944
- .feedback-survey-ces {
5945
- display: flex;
5946
- justify-content: space-between;
5947
- gap: var(--spacing-2);
5948
- }
5949
-
5950
- .feedback-survey-ces-btn {
5951
- flex: 1;
5952
- height: 40px;
5953
- padding: 0 var(--spacing-2);
5954
- border: 1px solid var(--color-border);
5955
- border-radius: var(--radius-md);
5956
- background: var(--color-surface);
5957
- cursor: pointer;
5958
- font-size: var(--font-size-xs);
5959
- font-weight: var(--font-weight-medium);
5960
- color: var(--color-text-primary);
5961
- transition: all var(--transition-fast);
5962
- font-family: inherit;
5963
- text-align: center;
5964
- }
5965
-
5966
- .feedback-survey-ces-btn:hover {
5967
- background: var(--color-primary-light);
5968
- border-color: var(--color-primary-border);
5969
- color: var(--color-primary);
5970
- }
5971
-
5972
- .feedback-survey-ces-btn.selected {
5973
- background: var(--color-primary-light);
5974
- border-color: var(--color-primary);
5975
- color: var(--color-primary-active);
5976
- }
5977
-
5978
- /* ========================================
5979
- CES LIST
5980
- ======================================== */
5981
-
5982
- .feedback-survey-ces-list {
5983
- display: flex;
5984
- flex-direction: column;
5985
- gap: var(--spacing-2);
5986
- }
5987
-
5988
- .feedback-survey-ces-list-btn {
5989
- width: 100%;
5990
- height: 40px;
5991
- padding: 0 var(--spacing-4);
5992
- border: 1px solid var(--color-border);
5993
- border-radius: var(--radius-md);
5994
- background: var(--color-surface);
5995
- cursor: pointer;
5996
- font-size: var(--font-size-base);
5997
- font-weight: var(--font-weight-medium);
5998
- color: var(--color-text-primary);
5999
- transition: all var(--transition-fast);
6000
- font-family: inherit;
6001
- text-align: left;
6002
- display: flex;
6003
- align-items: center;
6004
- justify-content: space-between;
6005
- }
6006
-
6007
- .feedback-survey-ces-list-btn:hover {
6008
- background: var(--color-primary-light);
6009
- border-color: var(--color-primary-border);
6010
- color: var(--color-primary);
6011
- }
6012
-
6013
- .feedback-survey-ces-list-btn.selected {
6014
- background: var(--color-primary-light);
6015
- border-color: var(--color-primary);
6016
- color: var(--color-primary-active);
6017
- }
6018
-
6019
- /* ========================================
6020
- SELECTION INDICATOR (choice & CES list)
6021
- ======================================== */
6022
-
6023
- .feedback-survey-ces-list-btn::after,
6024
- .feedback-survey-page-choice-btn::after {
6025
- content: '';
6026
- width: 18px;
6027
- height: 18px;
6028
- border-radius: 50%;
6029
- border: 1.5px solid var(--color-neutral-300);
6030
- flex-shrink: 0;
6031
- background: transparent;
6032
- background-size: 10px 10px;
6033
- background-repeat: no-repeat;
6034
- background-position: center;
6035
- transition: all var(--transition-fast);
5948
+ .feedback-survey-csat-btn:active {
5949
+ transform: scale(1.05) translateY(1px);
5950
+ transition-duration: 100ms;
6036
5951
  }
6037
5952
 
6038
- .feedback-survey-ces-list-btn.selected::after,
6039
- .feedback-survey-page-choice-btn.selected::after {
6040
- border-color: var(--color-primary);
6041
- background-color: var(--color-primary);
6042
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpolyline points='2,6.5 5,9.5 10,3' stroke='white' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
5953
+ .feedback-survey-csat-btn.selected:active {
5954
+ transform: scale(1.2) translateY(1px);
6043
5955
  }
6044
5956
 
6045
5957
  /* ========================================
6046
- RATING SCALE (generic)
5958
+ NUMBER RATING (segmented scale)
6047
5959
  ======================================== */
6048
5960
 
6049
- .feedback-survey-stars {
6050
- display: flex;
6051
- gap: var(--spacing-4);
6052
- justify-content: center;
6053
- }
6054
-
6055
- .feedback-survey-star-btn {
6056
- background: none;
6057
- border: none;
6058
- cursor: pointer;
6059
- font-size: 2.75rem;
6060
- color: var(--color-neutral-300);
6061
- padding: 0;
6062
- line-height: 1;
6063
- transition: color var(--transition-fast), transform var(--transition-fast);
6064
- }
6065
-
6066
- .feedback-survey-star-btn.filled,
6067
- .feedback-survey-star-btn.hovered {
6068
- color: #f59e0b;
6069
- }
6070
-
6071
- .feedback-survey-star-btn:active {
6072
- transform: scale(0.9);
6073
- }
6074
-
6075
5961
  .feedback-survey-rating-scale {
6076
5962
  display: flex;
6077
- gap: 0;
6078
- border: 1px solid var(--color-neutral-200);
6079
- border-radius: var(--radius-md);
6080
5963
  overflow: hidden;
5964
+ border: 1px solid var(--color-neutral-200);
5965
+ border-radius: 6px;
6081
5966
  background: var(--color-white);
6082
5967
  }
6083
5968
 
@@ -6092,9 +5977,9 @@
6092
5977
  cursor: pointer;
6093
5978
  font-size: clamp(14px, 3vw, 18px);
6094
5979
  font-weight: var(--font-weight-medium);
6095
- color: var(--color-text-primary);
5980
+ color: #374151;
6096
5981
  transition: background var(--transition-fast), color var(--transition-fast);
6097
- position: relative;
5982
+ font-family: inherit;
6098
5983
  }
6099
5984
 
6100
5985
  .feedback-survey-rating-scale-btn:last-child {
@@ -6118,59 +6003,68 @@
6118
6003
  box-shadow: inset 0 0 0 2px var(--color-primary);
6119
6004
  }
6120
6005
 
6006
+ .feedback-survey-rating-scale-btn:active {
6007
+ transform: translateY(1px);
6008
+ transition-duration: 100ms;
6009
+ }
6010
+
6121
6011
  /* ========================================
6122
- SCALE LABELS
6012
+ STARS
6123
6013
  ======================================== */
6124
6014
 
6125
- .feedback-survey-labels {
6015
+ .feedback-survey-stars {
6126
6016
  display: flex;
6127
- justify-content: space-between;
6128
- margin-top: var(--spacing-2);
6129
- font-size: var(--font-size-xs);
6130
- color: var(--color-text-tertiary);
6017
+ gap: var(--spacing-2);
6018
+ justify-content: center;
6131
6019
  }
6132
6020
 
6133
- .feedback-survey-rating-scale + .feedback-survey-labels {
6134
- margin-top: var(--spacing-3);
6135
- padding: 0 var(--spacing-1);
6136
- font-size: var(--font-size-sm);
6137
- color: var(--color-text-tertiary);
6021
+ .feedback-survey-star-btn {
6022
+ background: none;
6023
+ border: none;
6024
+ cursor: pointer;
6025
+ padding: 4px;
6026
+ width: 40px;
6027
+ height: 40px;
6028
+ flex-shrink: 0;
6029
+ line-height: 1;
6030
+ color: var(--color-neutral-300);
6031
+ transition: color var(--transition-fast), transform var(--transition-fast);
6032
+ display: flex;
6033
+ align-items: center;
6034
+ justify-content: center;
6138
6035
  }
6139
6036
 
6140
- /* ========================================
6141
- FREQUENCY
6142
- ======================================== */
6037
+ .feedback-survey-star-btn iconify-icon {
6038
+ display: block;
6039
+ pointer-events: none;
6040
+ flex-shrink: 0;
6041
+ }
6143
6042
 
6144
- .feedback-survey-frequency {
6145
- display: flex;
6146
- gap: var(--spacing-2);
6043
+ .feedback-survey-star-btn.filled,
6044
+ .feedback-survey-star-btn.hovered {
6045
+ color: #f59e0b;
6147
6046
  }
6148
6047
 
6149
- .feedback-survey-freq-btn {
6150
- flex: 1;
6151
- height: 40px;
6152
- padding: 0 var(--spacing-3);
6153
- border: 1px solid var(--color-border);
6154
- border-radius: var(--radius-md);
6155
- background: var(--color-surface);
6156
- cursor: pointer;
6157
- font-size: var(--font-size-sm);
6158
- font-weight: var(--font-weight-medium);
6159
- color: var(--color-text-primary);
6160
- transition: all var(--transition-fast);
6161
- font-family: inherit;
6048
+ .feedback-survey-star-btn:hover {
6049
+ color: #f59e0b;
6162
6050
  }
6163
6051
 
6164
- .feedback-survey-freq-btn:hover {
6165
- background: var(--color-primary-light);
6166
- border-color: var(--color-primary-border);
6167
- color: var(--color-primary);
6052
+ .feedback-survey-star-btn:active {
6053
+ transform: scale(0.9);
6054
+ transition-duration: 100ms;
6168
6055
  }
6169
6056
 
6170
- .feedback-survey-freq-btn.selected {
6171
- background: var(--color-primary-light);
6172
- border-color: var(--color-primary);
6173
- color: var(--color-primary-active);
6057
+ /* ========================================
6058
+ SCALE LABELS
6059
+ ======================================== */
6060
+
6061
+ .feedback-survey-labels {
6062
+ display: flex;
6063
+ justify-content: space-between;
6064
+ margin-top: var(--spacing-2);
6065
+ padding: 0 var(--spacing-1);
6066
+ font-size: var(--font-size-xs);
6067
+ color: var(--color-text-tertiary);
6174
6068
  }
6175
6069
 
6176
6070
  /* ========================================
@@ -6206,50 +6100,6 @@
6206
6100
  box-shadow: 0 0 0 3px var(--color-primary-light);
6207
6101
  }
6208
6102
 
6209
- .feedback-survey-select {
6210
- width: 100%;
6211
- height: 40px;
6212
- padding: 0 var(--spacing-3);
6213
- border: 1px solid var(--color-border);
6214
- border-radius: var(--radius-md);
6215
- font-size: var(--font-size-base);
6216
- background: var(--color-white);
6217
- color: var(--color-text-primary);
6218
- font-family: inherit;
6219
- cursor: pointer;
6220
- transition: border-color var(--transition-base);
6221
- outline: none;
6222
- }
6223
-
6224
- .feedback-survey-select:focus {
6225
- border-color: var(--color-primary);
6226
- box-shadow: 0 0 0 3px var(--color-primary-light);
6227
- }
6228
-
6229
- .feedback-survey-input {
6230
- width: 100%;
6231
- height: 40px;
6232
- padding: 0 var(--spacing-3);
6233
- border: 1px solid var(--color-border);
6234
- border-radius: var(--radius-md);
6235
- font-size: var(--font-size-base);
6236
- background: var(--color-white);
6237
- color: var(--color-text-primary);
6238
- font-family: inherit;
6239
- box-sizing: border-box;
6240
- transition: border-color var(--transition-base);
6241
- outline: none;
6242
- }
6243
-
6244
- .feedback-survey-input::placeholder {
6245
- color: var(--color-text-tertiary);
6246
- }
6247
-
6248
- .feedback-survey-input:focus {
6249
- border-color: var(--color-primary);
6250
- box-shadow: 0 0 0 3px var(--color-primary-light);
6251
- }
6252
-
6253
6103
  /* ========================================
6254
6104
  MULTI-PAGE TEXT INPUT
6255
6105
  ======================================== */
@@ -6260,7 +6110,7 @@
6260
6110
  padding: var(--spacing-3);
6261
6111
  border: 1px solid var(--color-border);
6262
6112
  border-radius: var(--radius-md);
6263
- font-size: var(--font-size-base);
6113
+ font-size: var(--font-size-sm);
6264
6114
  font-family: inherit;
6265
6115
  background: var(--color-white);
6266
6116
  color: var(--color-text-primary);
@@ -6293,12 +6143,12 @@
6293
6143
  width: 100%;
6294
6144
  height: 40px;
6295
6145
  padding: 0 var(--spacing-4);
6296
- border: 1px solid var(--color-border);
6146
+ border: 1px solid var(--color-neutral-200);
6297
6147
  border-radius: var(--radius-md);
6298
- background: var(--color-surface);
6299
- color: var(--color-text-primary);
6148
+ background: var(--color-white);
6149
+ color: #374151;
6300
6150
  text-align: left;
6301
- font-size: var(--font-size-base);
6151
+ font-size: var(--font-size-sm);
6302
6152
  font-weight: var(--font-weight-medium);
6303
6153
  cursor: pointer;
6304
6154
  font-family: inherit;
@@ -6308,33 +6158,41 @@
6308
6158
  transition: all var(--transition-fast);
6309
6159
  }
6310
6160
 
6161
+ .feedback-survey-page-choice-btn::after {
6162
+ content: '';
6163
+ width: 18px;
6164
+ height: 18px;
6165
+ border-radius: 50%;
6166
+ border: 1.5px solid #D1D5DB;
6167
+ flex-shrink: 0;
6168
+ background: transparent;
6169
+ transition: all var(--transition-fast);
6170
+ }
6171
+
6311
6172
  .feedback-survey-page-choice-btn:hover {
6173
+ border-color: var(--color-primary);
6312
6174
  background: var(--color-primary-light);
6313
- border-color: var(--color-primary-border);
6314
6175
  color: var(--color-primary);
6315
6176
  }
6316
6177
 
6178
+ .feedback-survey-page-choice-btn:hover::after {
6179
+ border-color: var(--color-primary);
6180
+ }
6181
+
6317
6182
  .feedback-survey-page-choice-btn.selected {
6318
- background: var(--color-primary-light);
6319
6183
  border-color: var(--color-primary);
6184
+ background: var(--color-primary-light);
6320
6185
  color: var(--color-primary-active);
6321
6186
  }
6322
-
6323
- /* ========================================
6324
- LINK PAGE
6325
- ======================================== */
6326
-
6327
- .feedback-survey-link-page {
6328
- display: flex;
6329
- flex-direction: column;
6330
- gap: var(--spacing-3);
6187
+
6188
+ .feedback-survey-page-choice-btn.selected::after {
6189
+ border-color: var(--color-primary);
6190
+ background-color: var(--color-primary);
6331
6191
  }
6332
6192
 
6333
- .feedback-survey-link-text {
6334
- font-size: var(--font-size-base);
6335
- color: var(--color-text-secondary);
6336
- line-height: var(--line-height-relaxed);
6337
- margin: 0;
6193
+ .feedback-survey-page-choice-btn:active {
6194
+ transform: translateY(1px);
6195
+ transition-duration: 100ms;
6338
6196
  }
6339
6197
 
6340
6198
  /* ========================================
@@ -6353,9 +6211,9 @@
6353
6211
  min-height: 40px;
6354
6212
  border: 1px solid var(--color-border);
6355
6213
  border-radius: var(--radius-md);
6356
- background: var(--color-surface);
6214
+ background: var(--color-white);
6357
6215
  color: var(--color-text-secondary);
6358
- font-size: var(--font-size-base);
6216
+ font-size: var(--font-size-sm);
6359
6217
  font-weight: var(--font-weight-medium);
6360
6218
  cursor: pointer;
6361
6219
  font-family: inherit;
@@ -6374,8 +6232,13 @@
6374
6232
  color: var(--color-text-primary);
6375
6233
  }
6376
6234
 
6235
+ .feedback-survey-back:active {
6236
+ transform: translateY(1px);
6237
+ transition-duration: 100ms;
6238
+ }
6239
+
6377
6240
  /* ========================================
6378
- SUBMIT & LINK BUTTON
6241
+ SUBMIT BUTTON
6379
6242
  ======================================== */
6380
6243
 
6381
6244
  .feedback-survey-submit {
@@ -6390,7 +6253,7 @@
6390
6253
  color: #ffffff;
6391
6254
  border: 1px solid var(--color-primary);
6392
6255
  border-radius: var(--radius-md);
6393
- font-size: var(--font-size-base);
6256
+ font-size: var(--font-size-sm);
6394
6257
  font-weight: var(--font-weight-medium);
6395
6258
  cursor: pointer;
6396
6259
  font-family: inherit;
@@ -6408,43 +6271,14 @@
6408
6271
  cursor: not-allowed;
6409
6272
  }
6410
6273
 
6411
- .feedback-survey-link-btn {
6412
- display: flex;
6413
- align-items: center;
6414
- justify-content: center;
6415
- gap: var(--spacing-2);
6416
- width: 100%;
6417
- min-height: 40px;
6418
- padding: 0 var(--spacing-4);
6419
- background: var(--color-primary);
6420
- color: #ffffff;
6421
- border: 1px solid var(--color-primary);
6422
- border-radius: var(--radius-md);
6423
- font-size: var(--font-size-base);
6424
- font-weight: var(--font-weight-medium);
6425
- cursor: pointer;
6426
- font-family: inherit;
6427
- text-align: center;
6428
- text-decoration: none;
6429
- transition: all var(--transition-base);
6430
- }
6431
-
6432
- .feedback-survey-link-btn:hover {
6433
- background: var(--color-primary-hover);
6434
- border-color: var(--color-primary-hover);
6435
- color: var(--color-white);
6436
- text-decoration: none;
6437
- }
6438
-
6439
- .feedback-survey-link-btn iconify-icon,
6440
- .feedback-survey-submit iconify-icon {
6441
- flex-shrink: 0;
6442
- color: #ffffff;
6274
+ .feedback-survey-submit:active:not(:disabled) {
6275
+ transform: translateY(1px);
6276
+ transition-duration: 100ms;
6443
6277
  }
6444
6278
 
6279
+ .feedback-survey-submit iconify-icon,
6445
6280
  .feedback-survey-back iconify-icon {
6446
6281
  flex-shrink: 0;
6447
- color: currentColor;
6448
6282
  }
6449
6283
 
6450
6284
  /* ========================================
@@ -6469,47 +6303,64 @@
6469
6303
  }
6470
6304
 
6471
6305
  /* ========================================
6472
- DARK MODE — SELECTED STATE OVERRIDES
6306
+ THANK YOU SCREEN
6473
6307
  ======================================== */
6474
6308
 
6475
- .feedback-survey-theme-dark .feedback-survey-ces-list-btn.selected,
6476
- .feedback-survey-theme-dark .feedback-survey-page-choice-btn.selected,
6477
- .feedback-survey-theme-dark .feedback-survey-freq-btn.selected,
6478
- .feedback-survey-theme-dark .feedback-survey-ces-btn.selected,
6479
- .feedback-survey-theme-dark .feedback-survey-nps-btn.selected,
6480
- .feedback-survey-theme-dark .feedback-survey-rating-scale-btn.selected {
6481
- color: var(--color-text-primary);
6309
+ .feedback-survey-thankyou {
6310
+ display: flex;
6311
+ flex-direction: column;
6312
+ align-items: center;
6313
+ text-align: center;
6314
+ padding: var(--spacing-6) 0;
6482
6315
  }
6483
6316
 
6484
- /* ========================================
6485
- PRESS EFFECT
6486
- ======================================== */
6317
+ .feedback-survey-thankyou-icon {
6318
+ color: #10b981;
6319
+ margin-bottom: var(--spacing-4);
6320
+ display: block;
6321
+ }
6487
6322
 
6488
- .feedback-survey-close:active,
6489
- .feedback-survey-submit:active,
6490
- .feedback-survey-back:active,
6491
- .feedback-survey-link-btn:active,
6492
- .feedback-survey-ces-btn:active,
6493
- .feedback-survey-ces-list-btn:active,
6494
- .feedback-survey-page-choice-btn:active,
6495
- .feedback-survey-freq-btn:active,
6496
- .feedback-survey-rating-scale-btn:active,
6497
- .feedback-survey-nps-btn:active {
6498
- transform: translateY(1px);
6499
- transition-duration: 100ms;
6323
+ .feedback-survey-thankyou-title {
6324
+ margin: 0;
6325
+ font-size: var(--font-size-xl);
6326
+ font-weight: var(--font-weight-semibold);
6327
+ line-height: var(--line-height-snug);
6328
+ color: var(--color-text-primary);
6500
6329
  }
6501
6330
 
6502
- .feedback-survey-nps-btn.selected:active {
6503
- transform: scale(1.06) translateY(1px);
6331
+ .feedback-survey-thankyou-btn {
6332
+ margin-top: var(--spacing-5);
6333
+ display: inline-flex;
6334
+ align-items: center;
6335
+ justify-content: center;
6336
+ gap: var(--spacing-2);
6337
+ height: 40px;
6338
+ padding: 0 var(--spacing-6);
6339
+ background: var(--color-primary);
6340
+ color: #ffffff;
6341
+ border: 1px solid var(--color-primary);
6342
+ border-radius: var(--radius-md);
6343
+ font-size: var(--font-size-sm);
6344
+ font-weight: var(--font-weight-medium);
6345
+ text-decoration: none;
6346
+ transition: all var(--transition-base);
6504
6347
  }
6505
6348
 
6506
- .feedback-survey-csat-btn:active {
6507
- transform: scale(1.05) translateY(1px);
6508
- transition-duration: 100ms;
6349
+ .feedback-survey-thankyou-btn:hover {
6350
+ background: var(--color-primary-hover);
6351
+ border-color: var(--color-primary-hover);
6352
+ color: #ffffff;
6353
+ text-decoration: none;
6509
6354
  }
6510
6355
 
6511
- .feedback-survey-csat-btn.selected:active {
6512
- transform: scale(1.2) translateY(1px);
6356
+ /* ========================================
6357
+ DARK MODE — SELECTED STATE OVERRIDES
6358
+ ======================================== */
6359
+
6360
+ .feedback-survey-theme-dark .feedback-survey-page-choice-btn.selected,
6361
+ .feedback-survey-theme-dark .feedback-survey-rating-scale-btn.selected,
6362
+ .feedback-survey-theme-dark .feedback-survey-nps-btn.selected {
6363
+ color: var(--color-text-primary);
6513
6364
  }
6514
6365
 
6515
6366
  /* ========================================
@@ -6542,22 +6393,10 @@
6542
6393
  flex-shrink: 0;
6543
6394
  }
6544
6395
 
6545
- .product7-notification-success {
6546
- background: #037F0C;
6547
- }
6548
-
6549
- .product7-notification-error {
6550
- background: #D13212;
6551
- }
6552
-
6553
- .product7-notification-warning {
6554
- background: #FF9900;
6555
- color: #000;
6556
- }
6557
-
6558
- .product7-notification-info {
6559
- background: #0972D3;
6560
- }
6396
+ .product7-notification-success { background: #037F0C; }
6397
+ .product7-notification-error { background: #D13212; }
6398
+ .product7-notification-warning { background: #FF9900; color: #000; }
6399
+ .product7-notification-info { background: #0972D3; }
6561
6400
 
6562
6401
  /* ========================================
6563
6402
  RESPONSIVE
@@ -6569,7 +6408,7 @@
6569
6408
  padding: var(--spacing-5);
6570
6409
  }
6571
6410
 
6572
- .feedback-survey-nps-btn {
6411
+ .feedback-survey-nps-btn {
6573
6412
  font-size: var(--font-size-xs);
6574
6413
  }
6575
6414
 
@@ -6590,10 +6429,6 @@
6590
6429
  .feedback-survey-rating-scale-btn {
6591
6430
  font-size: clamp(13px, 5vw, 16px);
6592
6431
  }
6593
-
6594
- .feedback-survey-rating-scale + .feedback-survey-labels {
6595
- font-size: var(--font-size-xs);
6596
- }
6597
6432
  }
6598
6433
  `;
6599
6434
 
@@ -8255,152 +8090,9 @@
8255
8090
 
8256
8091
  setPlaceholder(field, placeholder) {
8257
8092
  const input = this.element?.querySelector(`[name="${field}"]`);
8258
- if (input) {
8259
- input.placeholder = placeholder;
8260
- }
8261
- }
8262
- }
8263
-
8264
- var BUNDLED_SOUND = "data:audio/mpeg;base64,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BeaJKOtqtegdfu08KKta9TmppaKVKbNRgAAdr/tXGB6CSCPl1Lelt7XW7T01ifVk2zjE1bLW839346gs//uAZPGAAtMh2Hn4GlhT52rfPeJdDAirVe28aaE2Dmr9tY0siLho4mUCDpWMFgQGgu42pLnLawWb/bpWNprQxluj9TNaXJSgOIMS1KzM0TRIAAAABFakEh3cgBQEGVwwSAstoCBiYpGhkVAplAwJmPAkYLCBkEDgYHpEhgdJRk+AeYkqaA6eReiyrxNIvmnxxStER14EjE2/9hljaO2siCoAhzKnpuRt269O0veD7Pq/uNbdzt6jfydzch/Kkpf1/dcqV6ta/y3Y1MWIft8iMqtZzUahrWPO71nqvG43fsROXu5Y3KZJGnRZbEH1clnOWX//OZ/+2WTnxeAH4ZfTSxQdl7ovLbXkoM0tW5UzXqqe3b9bPWP/+H7q59vrHa/P1WVuvIHDdeijc/LKqG114l3Joq5VSQSsRUcUBhEnmWs49v5f///////////////y/mff///////////////3Ad21LEZyZxNSU0SUaZb/+8Bk6AADBiBVfWGgCEbieq+nmAEjzhFJ+cyQBEdCKT85gkCgwCAAAAA6AP0AywXlGoy0hpYVBKCMGkNVAtKWyXWFQkQg10C3jJ4dCWsMS6ezji0j3yF6W6MVa5lLJbaXvIFSNMi8Vdp4aejr0kYgJ/IpLXJpq0lmN4S38scPty+3K4brc1En1pL+vzx/k/bwt3IYllNldscl0R/HlzH9/zJ2IEd+3kzt34vWlVWVWqbn5Z/njz8O/+aXAXCHDZovNNc0AZypebBMlXypavJwV2u4yFL1vG4qA//93+9d/ff/Fg5dCKWEFHZcd41TwOim499QNk7qNZnHhm2uvA4NA5XIelTssq//5////////////////KFL24Op////////////////I3ifN9VM55RBBXv+tQAA8aAYzpLaSOxTi1EgJ6SJFPyUphVqcwGS1LvW/Hx+27zX1/f7Y2w5rdPTwuJkLERYGnMZHg0LksCgqGoKvEWkqYTKtOnRLvoGgFPadXgqdiKxbu2ws92sNCIOHN0xkAtG+saAAuK4rNZxyl0v8x2rfuXaCm7ruwZLSEFAQkKru7B2WMZy0qeUZjNZr5eXDP+8VVSOR/5cly6S3120bi5SXY5P/1/U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";
8265
-
8266
- /**
8267
- * NotificationSound — plays a soft ping when a new agent message arrives.
8268
- *
8269
- * Default: the bundled notification-sound.mp3 (inlined as base64 at build time).
8270
- * Falls back to a Web Audio API synthetic chime if the file was not bundled.
8271
- * Override: pass `soundUrl` (MP3/OGG/WAV URL or base64 data URI) to use a different file.
8272
- */
8273
-
8274
- class NotificationSound {
8275
- constructor({ soundUrl = BUNDLED_SOUND, volume = 0.4 } = {}) {
8276
- this._soundUrl = soundUrl;
8277
- this._volume = Math.min(1, Math.max(0, volume));
8278
- this._enabled = true;
8279
- this._audioCtx = null;
8280
- this._audioBuffer = null;
8281
- this._loadPromise = null;
8282
-
8283
- if (soundUrl) {
8284
- this._loadPromise = this._loadAudioFile(soundUrl);
8285
- }
8286
- }
8287
-
8288
- setEnabled(enabled) {
8289
- this._enabled = Boolean(enabled);
8290
- }
8291
-
8292
- setVolume(volume) {
8293
- this._volume = Math.min(1, Math.max(0, volume));
8294
- }
8295
-
8296
- async play() {
8297
- if (!this._enabled) return;
8298
- if (typeof window === 'undefined') return;
8299
-
8300
- try {
8301
- if (this._soundUrl) {
8302
- await this._playFile();
8303
- } else {
8304
- await this._playSynthetic();
8305
- }
8306
- } catch {
8307
- /* autoplay policy or context suspended — silent fail */
8308
- }
8309
- }
8310
-
8311
- // ── Private ────────────────────────────────────────────────────────────────
8312
-
8313
- _getAudioContext() {
8314
- if (!this._audioCtx || this._audioCtx.state === 'closed') {
8315
- const AudioContext = window.AudioContext || window.webkitAudioContext;
8316
- if (!AudioContext) return null;
8317
- this._audioCtx = new AudioContext();
8318
- }
8319
- return this._audioCtx;
8320
- }
8321
-
8322
- /**
8323
- * Synthetic two-tone chime via Web Audio API — no file required.
8324
- * • First tone: 880 Hz, 0–80 ms
8325
- * • Second tone: 1100 Hz, 60–160 ms
8326
- * Sounds like a gentle message ping.
8327
- */
8328
- async _playSynthetic() {
8329
- const ctx = this._getAudioContext();
8330
- if (!ctx) return;
8331
-
8332
- if (ctx.state === 'suspended') {
8333
- await ctx.resume();
8334
- }
8335
-
8336
- const now = ctx.currentTime;
8337
- const vol = this._volume;
8338
-
8339
- const tones = [
8340
- { freq: 880, start: 0, end: 0.08 },
8341
- { freq: 1100, start: 0.06, end: 0.16 },
8342
- ];
8343
-
8344
- tones.forEach(({ freq, start, end }) => {
8345
- const osc = ctx.createOscillator();
8346
- const gain = ctx.createGain();
8347
-
8348
- osc.type = 'sine';
8349
- osc.frequency.value = freq;
8350
-
8351
- gain.gain.setValueAtTime(0, now + start);
8352
- gain.gain.linearRampToValueAtTime(vol, now + start + 0.01);
8353
- gain.gain.linearRampToValueAtTime(0, now + end);
8354
-
8355
- osc.connect(gain);
8356
- gain.connect(ctx.destination);
8357
-
8358
- osc.start(now + start);
8359
- osc.stop(now + end + 0.01);
8360
- });
8361
- }
8362
-
8363
- async _loadAudioFile(url) {
8364
- try {
8365
- const ctx = this._getAudioContext();
8366
- if (!ctx) return;
8367
-
8368
- const response = await fetch(url);
8369
- const arrayBuffer = await response.arrayBuffer();
8370
- this._audioBuffer = await ctx.decodeAudioData(arrayBuffer);
8371
- } catch {
8372
- /* failed to load — fall back to synthetic */
8373
- this._soundUrl = null;
8374
- }
8375
- }
8376
-
8377
- async _playFile() {
8378
- if (this._loadPromise) {
8379
- await this._loadPromise;
8380
- this._loadPromise = null;
8381
- }
8382
-
8383
- if (!this._audioBuffer) {
8384
- this._playSynthetic();
8385
- return;
8386
- }
8387
-
8388
- const ctx = this._getAudioContext();
8389
- if (!ctx) return;
8390
-
8391
- if (ctx.state === 'suspended') {
8392
- await ctx.resume();
8393
- }
8394
-
8395
- const source = ctx.createBufferSource();
8396
- const gain = ctx.createGain();
8397
-
8398
- source.buffer = this._audioBuffer;
8399
- gain.gain.value = this._volume;
8400
-
8401
- source.connect(gain);
8402
- gain.connect(ctx.destination);
8403
- source.start();
8093
+ if (input) {
8094
+ input.placeholder = placeholder;
8095
+ }
8404
8096
  }
8405
8097
  }
8406
8098
 
@@ -8795,6 +8487,149 @@
8795
8487
  }
8796
8488
  }
8797
8489
 
8490
+ var BUNDLED_SOUND = "data:audio/mpeg;base64,SUQzBAAAAAAAGFRTU0UAAAAOAAADTGF2ZjUyLjExMS4wAP/7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhpbmcAAAAHAAAAHAAAIwgAHBwcNDQ0ND4+PlNTU1NfX190dHR0gICAioqKipSUlJSdnZ2oqKiosrKyu7u7u8bGxs7Ozs7X19fX3d3d4uLi4uXl5ejo6Ojr6+vu7u7u8fHx8fT09Pf39/f6+vr9/f39////AAAAAP/70GQAAAFZANHlBAAIMYAaXaCAARjV1Un5yIIKOJpo/zmAASTQWo7TdQAWD5toISgIYPg/lAQBCJw/+XP/UcKHFg++oEPwQ5c/9Rz+IAwCUm47pbZVAAROD4fBAEAQBAEw+XB8HwQBAEAQwffDHBM//Ln/iAEKwf/Lv9QIHPhjQAUrwgq4irMio5s5BUEAAAHCSeMAiNK062DzEZqDg43EwYIywBjGwcFiG8BeOXiQFAASMAAQRyHqBtpfAbggmYC5BhCyQyoANAEQsoSiRAZEc4oichtjvICKXDpy4bpkNJoXw1xzCLEwPouEsQMiZPjoEBDw4iZJUeSdNEFEoQIkCCEabjjJgrk0meMVGdJJOmx8qGxECcKZfTZRsmaIPdlysyZxRui91rqp7sv1TUwupJd/+3//onkM66K0mzVX//////8ydhEqptEMhmJZZVf3aRpEAAAFKRxTJQBaadeApgkSDQ1AQCpFGDFQEHQVfpsrtV+/z1gdSkjncSxSCceMSpHAuhKaWPxiG37ZjEW2o3XkG+6+pX+cZU6F6MX4s6EapLF/LL6lLZp7tWQWPj09HaTdNeltynw7jc3nu3P0FJAmeu43JqrUlcwr/Rydbmn1F/KqZXIAEAMkdbRou7ktcejaANCJAAlFZ4FRga9Rg2UNPqzFDTK/JF4lEjEo09F7NRDDECs5Y4DAY5JvN/EzKTZIIwMRRtNOGDSgk4VhBxa1pu4MJi04KIDFh4IcgcWJhmICJatIxBYWBQMALceRMFi67EvgcGbdmIRFOaG2VtPzccu+XJHgMtokMrl75iGZ3G5K8J+RxS8Dg9HtYBSsMAUSwEANxhuzTQ1Cqt6ksWXUqzytzNW3UHWwvRrk3bschmMwmaprXYvWkd+Uw/fj8rfyUu/EYHfySRV33Dh7Vret67qZ3S4f/9y/eWPxStez5n9vDd4LAwxk7/8LmlRxAAAgBVaDWNKCECikAADaBkbyhTdJ9AwALxiACrkxlRgIBqGRIrDGVBEw43AaJGBAGcJAQGiiAQQQOCr06EM9ZMDClaUEIiAodogZokISAGAhg8OEiMUYkQn1LVTI6dSJZctRJxCmZpW7TTWqe3hJJ6H/+9BktoAH0FVUfm9gAOeLaj/NaAAN/QFl/YWAIVwK7H+wMAT5bMWYy48/uaf7KZ7zn/moAlUj6Y0GW9Wcj5YyjU3q3W7vdmKb64D4wQv5UkdeWT0mrdLLbEq1v6kxhUy/95u5Bb9v/HoEfyP5Ou7Fa/VxwlXfq1eYfr/////xvZ4WJufl9THHPDLCmy/63aXYSWj/C4g//qb7VwAARXIiQR0NbJZURqcJH54mvNKXZpmUbACzEJJcteXbANB2YSXLL73w1zH6LbkPaRYbpNt7OO2W7rj6fui4t0Pjq43Q/v/+adzVcOdDr28f9w2Wdy5RPWXNmqKlHtZMnhYYBU/+txproyhDW/HJ/K6gAO2kkQA7v4IOiMyRrjYWrjxOU3Dk3DmefQiXGdNjEVgADik2LDDOCBcWMsNfVrEZwHGjfEw8NA0eBpYw80kkQi1KFKaGUKepd+3/0DK7EDnbt7U1XNeQEAVHf9kqBLzjxchaDngEDJaeEpfJ9oegJMJNIEqM0SUDozTc5R/85vvqZWKAgIUMfrSOzzpzjBdoTOJBsKgu4FhYGSRVY1Z5Sv8kVAoiFjQMBV36Hq+xJ/rIAADtXe63ACLsC0EudKI+PvNYWozM2vT+MFighxHKtMkGLP9V3n2v4OsZ/+i5WNZ5AbMuzfVnVq5VdiolNpio6q3tfysZRKgJwqWIhoekJp/6Ku5UQADPT2xtM6skVsL6KlTcpIeUOZk7hODETSqZzJfApYpusk8SP94xv+PLP/gmKT4DkuZUkmxnl9I+KZBZYc1IsY0FrTpqfaPJIvDCgg2SKsIpVStst3hvu9r6qP+ui/jlUQFF+3sjYO5OmwqbpxT1eFpa43QKABtkdSai5slNSzq0r6lDMJC0a4ZTymh555BgUPgZzQ4VBWKhy13G2VhsCH5R4OMsTWzV3+nobKeCAAZ997I3CudEoCwlmso4tZRVajMqeGWnRiTuKxkFdJug655kFnkj9JZ1cv3po1roaF1qQ9ZmBCAAaSKjTGLsrqSFwSeD7TQ5BeaJKOtqtegdfu08KKta9TmppaKVKbNRgAAdr/tXGB6CSCPl1Lelt7XW7T01ifVk2zjE1bLW839346gs//uAZPGAAtMh2Hn4GlhT52rfPeJdDAirVe28aaE2Dmr9tY0siLho4mUCDpWMFgQGgu42pLnLawWb/bpWNprQxluj9TNaXJSgOIMS1KzM0TRIAAAABFakEh3cgBQEGVwwSAstoCBiYpGhkVAplAwJmPAkYLCBkEDgYHpEhgdJRk+AeYkqaA6eReiyrxNIvmnxxStER14EjE2/9hljaO2siCoAhzKnpuRt269O0veD7Pq/uNbdzt6jfydzch/Kkpf1/dcqV6ta/y3Y1MWIft8iMqtZzUahrWPO71nqvG43fsROXu5Y3KZJGnRZbEH1clnOWX//OZ/+2WTnxeAH4ZfTSxQdl7ovLbXkoM0tW5UzXqqe3b9bPWP/+H7q59vrHa/P1WVuvIHDdeijc/LKqG114l3Joq5VSQSsRUcUBhEnmWs49v5f///////////////y/mff///////////////3Ad21LEZyZxNSU0SUaZb/+8Bk6AADBiBVfWGgCEbieq+nmAEjzhFJ+cyQBEdCKT85gkCgwCAAAAA6AP0AywXlGoy0hpYVBKCMGkNVAtKWyXWFQkQg10C3jJ4dCWsMS6ezji0j3yF6W6MVa5lLJbaXvIFSNMi8Vdp4aejr0kYgJ/IpLXJpq0lmN4S38scPty+3K4brc1En1pL+vzx/k/bwt3IYllNldscl0R/HlzH9/zJ2IEd+3kzt34vWlVWVWqbn5Z/njz8O/+aXAXCHDZovNNc0AZypebBMlXypavJwV2u4yFL1vG4qA//93+9d/ff/Fg5dCKWEFHZcd41TwOim499QNk7qNZnHhm2uvA4NA5XIelTssq//5////////////////KFL24Op////////////////I3ifN9VM55RBBXv+tQAA8aAYzpLaSOxTi1EgJ6SJFPyUphVqcwGS1LvW/Hx+27zX1/f7Y2w5rdPTwuJkLERYGnMZHg0LksCgqGoKvEWkqYTKtOnRLvoGgFPadXgqdiKxbu2ws92sNCIOHN0xkAtG+saAAuK4rNZxyl0v8x2rfuXaCm7ruwZLSEFAQkKru7B2WMZy0qeUZjNZr5eXDP+8VVSOR/5cly6S3120bi5SXY5P/1/U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";
8491
+
8492
+ /**
8493
+ * NotificationSound — plays a soft ping when a new agent message arrives.
8494
+ *
8495
+ * Default: the bundled notification-sound.mp3 (inlined as base64 at build time).
8496
+ * Falls back to a Web Audio API synthetic chime if the file was not bundled.
8497
+ * Override: pass `soundUrl` (MP3/OGG/WAV URL or base64 data URI) to use a different file.
8498
+ */
8499
+
8500
+ class NotificationSound {
8501
+ constructor({ soundUrl = BUNDLED_SOUND, volume = 0.4 } = {}) {
8502
+ this._soundUrl = soundUrl;
8503
+ this._volume = Math.min(1, Math.max(0, volume));
8504
+ this._enabled = true;
8505
+ this._audioCtx = null;
8506
+ this._audioBuffer = null;
8507
+ this._loadPromise = null;
8508
+
8509
+ if (soundUrl) {
8510
+ this._loadPromise = this._loadAudioFile(soundUrl);
8511
+ }
8512
+ }
8513
+
8514
+ setEnabled(enabled) {
8515
+ this._enabled = Boolean(enabled);
8516
+ }
8517
+
8518
+ setVolume(volume) {
8519
+ this._volume = Math.min(1, Math.max(0, volume));
8520
+ }
8521
+
8522
+ async play() {
8523
+ if (!this._enabled) return;
8524
+ if (typeof window === 'undefined') return;
8525
+
8526
+ try {
8527
+ if (this._soundUrl) {
8528
+ await this._playFile();
8529
+ } else {
8530
+ await this._playSynthetic();
8531
+ }
8532
+ } catch {
8533
+ /* autoplay policy or context suspended — silent fail */
8534
+ }
8535
+ }
8536
+
8537
+ // ── Private ────────────────────────────────────────────────────────────────
8538
+
8539
+ _getAudioContext() {
8540
+ if (!this._audioCtx || this._audioCtx.state === 'closed') {
8541
+ const AudioContext = window.AudioContext || window.webkitAudioContext;
8542
+ if (!AudioContext) return null;
8543
+ this._audioCtx = new AudioContext();
8544
+ }
8545
+ return this._audioCtx;
8546
+ }
8547
+
8548
+ /**
8549
+ * Synthetic two-tone chime via Web Audio API — no file required.
8550
+ * • First tone: 880 Hz, 0–80 ms
8551
+ * • Second tone: 1100 Hz, 60–160 ms
8552
+ * Sounds like a gentle message ping.
8553
+ */
8554
+ async _playSynthetic() {
8555
+ const ctx = this._getAudioContext();
8556
+ if (!ctx) return;
8557
+
8558
+ if (ctx.state === 'suspended') {
8559
+ await ctx.resume();
8560
+ }
8561
+
8562
+ const now = ctx.currentTime;
8563
+ const vol = this._volume;
8564
+
8565
+ const tones = [
8566
+ { freq: 880, start: 0, end: 0.08 },
8567
+ { freq: 1100, start: 0.06, end: 0.16 },
8568
+ ];
8569
+
8570
+ tones.forEach(({ freq, start, end }) => {
8571
+ const osc = ctx.createOscillator();
8572
+ const gain = ctx.createGain();
8573
+
8574
+ osc.type = 'sine';
8575
+ osc.frequency.value = freq;
8576
+
8577
+ gain.gain.setValueAtTime(0, now + start);
8578
+ gain.gain.linearRampToValueAtTime(vol, now + start + 0.01);
8579
+ gain.gain.linearRampToValueAtTime(0, now + end);
8580
+
8581
+ osc.connect(gain);
8582
+ gain.connect(ctx.destination);
8583
+
8584
+ osc.start(now + start);
8585
+ osc.stop(now + end + 0.01);
8586
+ });
8587
+ }
8588
+
8589
+ async _loadAudioFile(url) {
8590
+ try {
8591
+ const ctx = this._getAudioContext();
8592
+ if (!ctx) return;
8593
+
8594
+ const response = await fetch(url);
8595
+ const arrayBuffer = await response.arrayBuffer();
8596
+ this._audioBuffer = await ctx.decodeAudioData(arrayBuffer);
8597
+ } catch {
8598
+ /* failed to load — fall back to synthetic */
8599
+ this._soundUrl = null;
8600
+ }
8601
+ }
8602
+
8603
+ async _playFile() {
8604
+ if (this._loadPromise) {
8605
+ await this._loadPromise;
8606
+ this._loadPromise = null;
8607
+ }
8608
+
8609
+ if (!this._audioBuffer) {
8610
+ this._playSynthetic();
8611
+ return;
8612
+ }
8613
+
8614
+ const ctx = this._getAudioContext();
8615
+ if (!ctx) return;
8616
+
8617
+ if (ctx.state === 'suspended') {
8618
+ await ctx.resume();
8619
+ }
8620
+
8621
+ const source = ctx.createBufferSource();
8622
+ const gain = ctx.createGain();
8623
+
8624
+ source.buffer = this._audioBuffer;
8625
+ gain.gain.value = this._volume;
8626
+
8627
+ source.connect(gain);
8628
+ gain.connect(ctx.destination);
8629
+ source.start();
8630
+ }
8631
+ }
8632
+
8798
8633
  class MessengerState {
8799
8634
  constructor(options = {}) {
8800
8635
  this.currentView = 'home';
@@ -11524,12 +11359,16 @@
11524
11359
  this._wsUnsubscribers = [];
11525
11360
  this._feedbackWidget = null;
11526
11361
 
11527
- const notificationSoundOption = options.notificationSound !== undefined
11528
- ? options.notificationSound
11529
- : true;
11362
+ const notificationSoundOption =
11363
+ options.notificationSound !== undefined
11364
+ ? options.notificationSound
11365
+ : true;
11530
11366
 
11531
11367
  this._notificationSound = new NotificationSound({
11532
- soundUrl: typeof notificationSoundOption === 'string' ? notificationSoundOption : undefined,
11368
+ soundUrl:
11369
+ typeof notificationSoundOption === 'string'
11370
+ ? notificationSoundOption
11371
+ : undefined,
11533
11372
  volume: options.notificationVolume ?? 0.4,
11534
11373
  });
11535
11374
 
@@ -12538,6 +12377,8 @@
12538
12377
  : null,
12539
12378
  customQuestions: options.customQuestions || [],
12540
12379
  pages: Array.isArray(options.pages) ? options.pages : [],
12380
+ thankYouConfig:
12381
+ options.thankYouConfig || options.thank_you_config || null,
12541
12382
  respondentId: options.respondentId || null,
12542
12383
  email: options.email || null,
12543
12384
  onSubmit: options.onSubmit || null,
@@ -12866,10 +12707,6 @@
12866
12707
 
12867
12708
  _shouldShowActions() {
12868
12709
  if (this._isMultiPageSurvey()) {
12869
- const page = this._getCurrentPage();
12870
- if (page && page.type === 'link') {
12871
- return false;
12872
- }
12873
12710
  return true;
12874
12711
  }
12875
12712
  if (typeof this.surveyOptions.showSubmitButton === 'boolean') {
@@ -12918,8 +12755,6 @@
12918
12755
  return this._renderMultipleChoicePage(page);
12919
12756
  case 'text':
12920
12757
  return this._renderTextPage(page);
12921
- case 'link':
12922
- return this._renderLinkPage(page);
12923
12758
  default:
12924
12759
  return '';
12925
12760
  }
@@ -12927,62 +12762,36 @@
12927
12762
 
12928
12763
  _renderRatingPage(page) {
12929
12764
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
12930
- const config = page.ratingConfig || page.rating_config || {};
12765
+ const config = page.rating_config || page.ratingConfig || {};
12931
12766
  const scale = Number(config.scale) || 5;
12932
- const topSurveyType = this.surveyOptions.surveyType;
12933
- const configType = config.survey_type;
12934
- let ratingType;
12935
- if (topSurveyType === 'nps') {
12936
- ratingType = 'nps';
12937
- } else if (configType) {
12938
- ratingType = configType;
12939
- } else if (topSurveyType === 'ces') {
12940
- ratingType = 'ces';
12941
- } else if (topSurveyType === 'csat') {
12942
- ratingType = 'emoji';
12943
- } else {
12944
- ratingType = topSurveyType || 'csat';
12945
- }
12767
+ const ratingType = config.survey_type || 'number';
12946
12768
  const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
12947
12769
  const currentRating = pageAnswer.rating;
12948
- const defaultLowLabel =
12949
- ratingType === 'nps'
12950
- ? scale === 11
12951
- ? 'Not likely'
12952
- : 'Strongly Disagree'
12953
- : '';
12954
- const defaultHighLabel =
12955
- ratingType === 'nps'
12956
- ? scale === 11
12957
- ? 'Very likely'
12958
- : 'Strongly Agree'
12959
- : '';
12960
- const lowLabel =
12961
- config.low_label || this.surveyOptions.lowLabel || defaultLowLabel;
12962
- const highLabel =
12963
- config.high_label || this.surveyOptions.highLabel || defaultHighLabel;
12770
+
12771
+ const labelDefaults = {
12772
+ nps:
12773
+ scale === 11
12774
+ ? ['Not likely', 'Very likely']
12775
+ : ['Strongly Disagree', 'Strongly Agree'],
12776
+ emoji: ['Very dissatisfied', 'Very satisfied'],
12777
+ number: ['Poor', 'Excellent'],
12778
+ star: ['Poor', 'Excellent'],
12779
+ };
12780
+ const [defaultLow, defaultHigh] = labelDefaults[ratingType] || ['', ''];
12781
+ const lowLabel = config.low_label || defaultLow;
12782
+ const highLabel = config.high_label || defaultHigh;
12964
12783
  const labels = this._renderScaleLabels(lowLabel, highLabel);
12965
12784
 
12966
12785
  if (ratingType === 'nps') {
12967
- const npsScale = Number.isFinite(scale) && scale >= 2 ? scale : 5;
12786
+ const npsScale = Number.isFinite(scale) && scale >= 2 ? scale : 11;
12968
12787
  const start = npsScale === 11 ? 0 : 1;
12969
- const values = Array.from(
12970
- { length: npsScale },
12971
- (_, index) => start + index
12972
- );
12973
- const usesSegmentedScale = values.length <= 7;
12974
- const containerClass = usesSegmentedScale
12975
- ? 'feedback-survey-ces feedback-survey-rating-scale'
12976
- : 'feedback-survey-nps';
12977
- const buttonClass = usesSegmentedScale
12978
- ? 'feedback-survey-page-rating-btn feedback-survey-nps-btn feedback-survey-ces-btn feedback-survey-rating-scale-btn'
12979
- : 'feedback-survey-page-rating-btn feedback-survey-nps-btn';
12788
+ const values = Array.from({ length: npsScale }, (_, i) => start + i);
12980
12789
  return `
12981
- <div class="${containerClass}" data-page-id="${pageId}">
12790
+ <div class="feedback-survey-nps" data-page-id="${pageId}">
12982
12791
  ${values
12983
12792
  .map((n) => {
12984
12793
  const selected = currentRating === n ? ' selected' : '';
12985
- return `<button class="${buttonClass}${selected}" data-page-id="${pageId}" data-score="${n}">${n}</button>`;
12794
+ return `<button class="feedback-survey-page-rating-btn feedback-survey-nps-btn feedback-survey-nps-score-${n}${selected}" data-page-id="${pageId}" data-score="${n}">${n}</button>`;
12986
12795
  })
12987
12796
  .join('')}
12988
12797
  </div>
@@ -12990,28 +12799,7 @@
12990
12799
  `;
12991
12800
  }
12992
12801
 
12993
- if (ratingType === 'ces') {
12994
- const cesLabels = [
12995
- 'Very Difficult',
12996
- 'Difficult',
12997
- 'Neutral',
12998
- 'Easy',
12999
- 'Very Easy',
13000
- ];
13001
- return `
13002
- <div class="feedback-survey-ces-list" data-page-id="${pageId}">
13003
- ${cesLabels
13004
- .map((label, i) => {
13005
- const score = i + 1;
13006
- const selected = currentRating === score ? ' selected' : '';
13007
- return `<button class="feedback-survey-page-rating-btn feedback-survey-ces-list-btn${selected}" data-page-id="${pageId}" data-score="${score}">${label}</button>`;
13008
- })
13009
- .join('')}
13010
- </div>
13011
- `;
13012
- }
13013
-
13014
- if (ratingType === 'emoji' && scale === 5) {
12802
+ if (ratingType === 'emoji') {
13015
12803
  const emojis = [
13016
12804
  '\uD83D\uDE1E',
13017
12805
  '\uD83D\uDE15',
@@ -13019,9 +12807,12 @@
13019
12807
  '\uD83D\uDE42',
13020
12808
  '\uD83D\uDE04',
13021
12809
  ];
12810
+ const emojiScale =
12811
+ Number.isFinite(scale) && scale >= 2 ? Math.min(scale, 5) : 5;
13022
12812
  return `
13023
12813
  <div class="feedback-survey-csat" data-page-id="${pageId}">
13024
12814
  ${emojis
12815
+ .slice(0, emojiScale)
13025
12816
  .map((emoji, i) => {
13026
12817
  const score = i + 1;
13027
12818
  const selected = currentRating === score ? ' selected' : '';
@@ -13037,27 +12828,27 @@
13037
12828
  const starScale = Number.isFinite(scale) && scale >= 2 ? scale : 5;
13038
12829
  return `
13039
12830
  <div class="feedback-survey-stars" data-page-id="${pageId}">
13040
- ${[...Array(starScale).keys()]
13041
- .map((i) => {
13042
- const score = i + 1;
13043
- const filled = currentRating >= score ? ' filled' : '';
13044
- return `<button class="feedback-survey-page-rating-btn feedback-survey-star-btn${filled}" data-page-id="${pageId}" data-score="${score}">★</button>`;
13045
- })
13046
- .join('')}
12831
+ ${Array.from({ length: starScale }, (_, i) => {
12832
+ const score = i + 1;
12833
+ const filled =
12834
+ typeof currentRating === 'number' && currentRating >= score
12835
+ ? ' filled'
12836
+ : '';
12837
+ return `<button class="feedback-survey-page-rating-btn feedback-survey-star-btn${filled}" data-page-id="${pageId}" data-score="${score}"><iconify-icon icon="ph:star-duotone" width="32" height="32" style="pointer-events:none;"></iconify-icon></button>`;
12838
+ }).join('')}
13047
12839
  </div>
13048
12840
  ${labels}
13049
12841
  `;
13050
12842
  }
13051
12843
 
12844
+ const numScale = Number.isFinite(scale) && scale >= 2 ? scale : 5;
13052
12845
  return `
13053
12846
  <div class="feedback-survey-rating-scale" data-page-id="${pageId}">
13054
- ${[...Array(scale).keys()]
13055
- .map((i) => {
13056
- const score = i + 1;
13057
- const selected = currentRating === score ? ' selected' : '';
13058
- return `<button class="feedback-survey-page-rating-btn feedback-survey-rating-scale-btn${selected}" data-page-id="${pageId}" data-score="${score}">${score}</button>`;
13059
- })
13060
- .join('')}
12847
+ ${Array.from({ length: numScale }, (_, i) => {
12848
+ const score = i + 1;
12849
+ const selected = currentRating === score ? ' selected' : '';
12850
+ return `<button class="feedback-survey-page-rating-btn feedback-survey-rating-scale-btn${selected}" data-page-id="${pageId}" data-score="${score}">${score}</button>`;
12851
+ }).join('')}
13061
12852
  </div>
13062
12853
  ${labels}
13063
12854
  `;
@@ -13107,32 +12898,6 @@
13107
12898
  `;
13108
12899
  }
13109
12900
 
13110
- _renderLinkPage(page) {
13111
- const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
13112
- const config = page.link_config || page.linkConfig || {};
13113
- const buttonText = config.button_text || config.buttonText || 'Click here';
13114
- const linkText = config.link_text || config.linkText || '';
13115
- const redirectUrl = config.redirect_url || config.redirectUrl || '#';
13116
- const openIn = config.open_in || config.openIn || 'new_tab';
13117
- const target = openIn === 'new_tab' ? '_blank' : '_self';
13118
- const pageAnswer = this.surveyState.pageAnswers[pageId] || {};
13119
- const clicked = pageAnswer.clicked === true;
13120
-
13121
- const iconExternalLink = `<iconify-icon icon="ph:arrow-square-out-duotone" width="15" height="15"></iconify-icon>`;
13122
- return `
13123
- <div class="feedback-survey-link-page" data-page-id="${pageId}">
13124
- ${linkText ? `<p class="feedback-survey-link-text">${linkText}</p>` : ''}
13125
- <a class="feedback-survey-link-btn${clicked ? ' selected' : ''}"
13126
- href="${redirectUrl}"
13127
- target="${target}"
13128
- rel="noopener noreferrer"
13129
- data-page-id="${pageId}">
13130
- ${buttonText} ${iconExternalLink}
13131
- </a>
13132
- </div>
13133
- `;
13134
- }
13135
-
13136
12901
  _renderCustomQuestions() {
13137
12902
  if (
13138
12903
  !this.surveyOptions.customQuestions ||
@@ -13415,24 +13180,6 @@
13415
13180
  });
13416
13181
  }
13417
13182
  }
13418
-
13419
- if (page.type === 'link') {
13420
- this.surveyElement
13421
- .querySelectorAll('.feedback-survey-link-btn')
13422
- .forEach((btn) => {
13423
- btn.addEventListener('click', () => {
13424
- const pId = btn.dataset.pageId;
13425
- this._setPageAnswer(pId, { clicked: true });
13426
- btn.classList.add('selected');
13427
-
13428
- const navigation = page.afterThisPage || page.after_this_page;
13429
- const goesTo = navigation ? navigation.default : null;
13430
- if (!goesTo || goesTo === 'end_survey') {
13431
- setTimeout(() => this._handleSubmit(), 400);
13432
- }
13433
- });
13434
- });
13435
- }
13436
13183
  }
13437
13184
 
13438
13185
  _selectNPS(score) {
@@ -13441,11 +13188,7 @@
13441
13188
  .querySelectorAll('.feedback-survey-nps-btn')
13442
13189
  .forEach((btn) => {
13443
13190
  const btnScore = parseInt(btn.dataset.score);
13444
- if (btnScore === score) {
13445
- btn.classList.add('selected');
13446
- } else {
13447
- btn.classList.remove('selected');
13448
- }
13191
+ btn.classList.toggle('selected', btnScore === score);
13449
13192
  });
13450
13193
  this._maybeAutoSubmit();
13451
13194
  }
@@ -13456,50 +13199,16 @@
13456
13199
  .querySelectorAll('.feedback-survey-csat-btn')
13457
13200
  .forEach((btn) => {
13458
13201
  const btnScore = parseInt(btn.dataset.score);
13459
- if (btnScore === score) {
13460
- btn.classList.add('selected');
13461
- } else {
13462
- btn.classList.remove('selected');
13463
- }
13464
- });
13465
- this._maybeAutoSubmit();
13466
- }
13467
-
13468
- _selectCES(score) {
13469
- this.surveyState.score = score;
13470
- this.surveyElement
13471
- .querySelectorAll('.feedback-survey-ces-btn')
13472
- .forEach((btn) => {
13473
- const btnScore = parseInt(btn.dataset.score);
13474
- if (btnScore === score) {
13475
- btn.classList.add('selected');
13476
- } else {
13477
- btn.classList.remove('selected');
13478
- }
13202
+ btn.classList.toggle('selected', btnScore === score);
13479
13203
  });
13480
13204
  this._maybeAutoSubmit();
13481
13205
  }
13482
13206
 
13483
13207
  _maybeAutoSubmit() {
13484
- if (!this._shouldAutoSubmitOnSelect()) {
13485
- return;
13486
- }
13208
+ if (!this._shouldAutoSubmitOnSelect()) return;
13487
13209
  this._handleSubmit();
13488
13210
  }
13489
13211
 
13490
- _selectFrequency(freq) {
13491
- this.surveyState.customAnswers.frequency = freq;
13492
- this.surveyElement
13493
- .querySelectorAll('.feedback-survey-freq-btn')
13494
- .forEach((btn) => {
13495
- if (btn.dataset.freq === freq) {
13496
- btn.classList.add('selected');
13497
- } else {
13498
- btn.classList.remove('selected');
13499
- }
13500
- });
13501
- }
13502
-
13503
13212
  _setSubmitLoading(loading) {
13504
13213
  const btn = this.surveyElement?.querySelector('.feedback-survey-submit');
13505
13214
  if (!btn) return;
@@ -13579,8 +13288,7 @@
13579
13288
  await this.apiService.submitSurveyResponse(surveyId, responseData);
13580
13289
 
13581
13290
  this.sdk.eventBus.emit('survey:submitted', { widget: this, response });
13582
- this._closeSurvey();
13583
- this._showSuccessNotification();
13291
+ this._showThankYouScreen();
13584
13292
  } catch (error) {
13585
13293
  console.error('[SurveyWidget] Failed to submit survey:', error);
13586
13294
  this._showError('Something went wrong. Please try again.');
@@ -13616,9 +13324,8 @@
13616
13324
 
13617
13325
  _validateCurrentPage() {
13618
13326
  const page = this._getCurrentPage();
13619
- if (!page || page.required === false) return true;
13327
+ if (!page || page.required !== true) return true;
13620
13328
  const pageId = page.id || `page_${this.surveyState.currentPageIndex}`;
13621
-
13622
13329
  const answer = this.surveyState.pageAnswers[pageId] || {};
13623
13330
 
13624
13331
  if (page.type === 'rating') {
@@ -13629,9 +13336,10 @@
13629
13336
  }
13630
13337
 
13631
13338
  if (page.type === 'multiple_choice') {
13632
- const hasSingle = Boolean(answer.value);
13633
- const hasMany = Array.isArray(answer.values) && answer.values.length > 0;
13634
- if (!hasSingle && !hasMany) {
13339
+ const hasAnswer =
13340
+ Boolean(answer.value) ||
13341
+ (Array.isArray(answer.values) && answer.values.length > 0);
13342
+ if (!hasAnswer) {
13635
13343
  this._showError('Please select an option');
13636
13344
  return false;
13637
13345
  }
@@ -13644,55 +13352,88 @@
13644
13352
  }
13645
13353
  }
13646
13354
 
13647
- if (page.type === 'link') {
13648
- if (page.required && !answer.clicked) {
13649
- this._showError('Please click the link to continue');
13650
- return false;
13651
- }
13652
- }
13653
-
13654
13355
  return true;
13655
13356
  }
13656
13357
 
13657
13358
  _getNextPageIndex() {
13658
- if (!this._isMultiPageSurvey()) {
13659
- return -1;
13660
- }
13359
+ if (!this._isMultiPageSurvey()) return -1;
13661
13360
 
13662
13361
  const page = this._getCurrentPage();
13663
13362
  const total = this.surveyOptions.pages.length;
13664
13363
  const currentIndex = this.surveyState.currentPageIndex;
13665
13364
  const fallbackNext = currentIndex + 1 < total ? currentIndex + 1 : -1;
13666
- const navigation = page ? page.afterThisPage || page.after_this_page : null;
13667
- if (!navigation) {
13668
- return fallbackNext;
13669
- }
13365
+ const navigation = page ? page.after_this_page || page.afterThisPage : null;
13366
+ if (!navigation) return fallbackNext;
13670
13367
 
13671
- const nextValue = navigation.default;
13672
- if (!nextValue) {
13673
- return fallbackNext;
13674
- }
13368
+ const conditions = Array.isArray(navigation.conditions)
13369
+ ? navigation.conditions
13370
+ : [];
13371
+ const pageId = page.id || `page_${currentIndex}`;
13372
+ const answer = this.surveyState.pageAnswers[pageId] || {};
13675
13373
 
13676
- if (nextValue === 'end_survey') {
13677
- return -1;
13678
- }
13679
- if (nextValue === 'next_page' || nextValue === 'next') {
13680
- return fallbackNext;
13374
+ for (const condition of conditions) {
13375
+ if (this._evaluateCondition(condition, page, answer)) {
13376
+ return this._resolvePageTarget(condition.go_to, total, fallbackNext);
13377
+ }
13681
13378
  }
13682
13379
 
13683
- if (typeof nextValue === 'number') {
13684
- return nextValue >= 0 && nextValue < total ? nextValue : fallbackNext;
13380
+ return this._resolvePageTarget(navigation.default, total, fallbackNext);
13381
+ }
13382
+
13383
+ _evaluateCondition(condition, page, answer) {
13384
+ const { operator, values } = condition;
13385
+ if (!operator || !Array.isArray(values)) return false;
13386
+
13387
+ let answerValue = null;
13388
+ if (page.type === 'rating') {
13389
+ answerValue = typeof answer.rating === 'number' ? answer.rating : null;
13390
+ } else if (page.type === 'multiple_choice') {
13391
+ answerValue =
13392
+ answer.value ||
13393
+ (Array.isArray(answer.values) ? answer.values[0] : null);
13394
+ } else if (page.type === 'text') {
13395
+ answerValue = answer.text || null;
13396
+ }
13397
+
13398
+ if (operator === 'is_empty')
13399
+ return answerValue === null || answerValue === '';
13400
+ if (operator === 'not_empty')
13401
+ return answerValue !== null && answerValue !== '';
13402
+ if (answerValue === null) return false;
13403
+
13404
+ const [v1, v2] = values;
13405
+ switch (operator) {
13406
+ case 'equals':
13407
+ return String(answerValue) === String(v1);
13408
+ case 'greater_than':
13409
+ return Number(answerValue) > Number(v1);
13410
+ case 'less_than':
13411
+ return Number(answerValue) < Number(v1);
13412
+ case 'between':
13413
+ return (
13414
+ Number(answerValue) >= Number(v1) && Number(answerValue) <= Number(v2)
13415
+ );
13416
+ case 'contains':
13417
+ return String(answerValue).includes(String(v1));
13418
+ default:
13419
+ return false;
13685
13420
  }
13421
+ }
13686
13422
 
13687
- if (typeof nextValue === 'string') {
13688
- const normalizedId = nextValue.replace(/^page:/, '');
13689
- const pageIndex = this.surveyOptions.pages.findIndex(
13690
- (item) => item.id === normalizedId
13423
+ _resolvePageTarget(target, total, fallback) {
13424
+ if (!target) return fallback;
13425
+ if (target === 'end_survey') return -1;
13426
+ if (target === 'next_page' || target === 'next') return fallback;
13427
+ if (typeof target === 'number')
13428
+ return target >= 0 && target < total ? target : fallback;
13429
+ if (typeof target === 'string') {
13430
+ const normalizedId = target.replace(/^page:/, '');
13431
+ const idx = this.surveyOptions.pages.findIndex(
13432
+ (p) => p.id === normalizedId
13691
13433
  );
13692
- return pageIndex >= 0 ? pageIndex : fallbackNext;
13434
+ return idx >= 0 ? idx : fallback;
13693
13435
  }
13694
-
13695
- return fallbackNext;
13436
+ return fallback;
13696
13437
  }
13697
13438
 
13698
13439
  _getSubmissionRating() {
@@ -13797,23 +13538,45 @@
13797
13538
  setTimeout(() => error.remove(), 3000);
13798
13539
  }
13799
13540
 
13800
- _showSuccessNotification() {
13801
- const notification = document.createElement('div');
13802
- notification.className =
13803
- 'product7-notification product7-notification-success';
13804
- notification.innerHTML = `
13805
- <div>
13806
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path d="M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" fill="currentColor"/></svg>
13807
- <span>Thank you for your feedback!</span>
13541
+ _showThankYouScreen() {
13542
+ if (!this.surveyElement) return;
13543
+
13544
+ const config = this.surveyOptions.thankYouConfig || {};
13545
+ const title = config.title || 'Thanks for your feedback!';
13546
+ const buttonText = config.button_text || null;
13547
+ const buttonUrl = config.button_url || '#';
13548
+
13549
+ if (this._escapeHandler) {
13550
+ document.removeEventListener('keydown', this._escapeHandler);
13551
+ this._escapeHandler = null;
13552
+ }
13553
+
13554
+ this.surveyElement.innerHTML = `
13555
+ <button class="feedback-survey-close"><iconify-icon icon="ph:x-duotone" width="16" height="16"></iconify-icon></button>
13556
+ <div class="feedback-survey-thankyou">
13557
+ <iconify-icon icon="ph:check-circle-duotone" width="48" height="48" class="feedback-survey-thankyou-icon"></iconify-icon>
13558
+ <h3 class="feedback-survey-thankyou-title">${title}</h3>
13559
+ ${
13560
+ buttonText
13561
+ ? `
13562
+ <a class="feedback-survey-thankyou-btn" href="${buttonUrl}" target="_blank" rel="noopener noreferrer">
13563
+ ${buttonText}
13564
+ <iconify-icon icon="ph:arrow-square-out-duotone" width="15" height="15" style="pointer-events:none;"></iconify-icon>
13565
+ </a>`
13566
+ : ''
13567
+ }
13808
13568
  </div>
13809
13569
  `;
13810
- document.body.appendChild(notification);
13811
13570
 
13812
- setTimeout(() => {
13813
- notification.style.opacity = '0';
13814
- notification.style.transition = 'opacity 0.3s ease';
13815
- setTimeout(() => notification.remove(), 300);
13816
- }, 3000);
13571
+ const closeBtn = this.surveyElement.querySelector('.feedback-survey-close');
13572
+ if (closeBtn) closeBtn.addEventListener('click', () => this._closeSurvey());
13573
+
13574
+ setTimeout(
13575
+ () => {
13576
+ if (this.surveyElement) this._closeSurvey();
13577
+ },
13578
+ buttonText ? 6000 : 3500
13579
+ );
13817
13580
  }
13818
13581
 
13819
13582
  _closeSurvey(resetState = true, immediate = false) {
@@ -14286,6 +14049,7 @@
14286
14049
  showDescription: normalizedOptions.showDescription,
14287
14050
  customQuestions: normalizedOptions.customQuestions,
14288
14051
  pages: normalizedOptions.pages,
14052
+ thankYouConfig: normalizedOptions.thankYouConfig,
14289
14053
  respondentId: normalizedOptions.respondentId,
14290
14054
  email: normalizedOptions.email,
14291
14055
  onSubmit: normalizedOptions.onSubmit,
@@ -14429,6 +14193,7 @@
14429
14193
  survey.custom_questions ||
14430
14194
  survey.questions ||
14431
14195
  [],
14196
+ thankYouConfig: survey.thankYouConfig || survey.thank_you_config || null,
14432
14197
  pages: this._normalizeSurveyPages(survey.pages || []),
14433
14198
  };
14434
14199
  }
@@ -14445,7 +14210,7 @@
14445
14210
  title: page.title || '',
14446
14211
  description: page.description || '',
14447
14212
  placeholder: page.placeholder || '',
14448
- required: page.required !== false,
14213
+ required: page.required === true,
14449
14214
  position: page.position ?? index,
14450
14215
  ratingConfig: page.ratingConfig || page.rating_config || null,
14451
14216
  multipleChoiceConfig: