@product7/product7-js 0.7.0 → 0.7.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@product7/product7-js",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "JavaScript SDK for integrating Product7 feedback widgets into any website",
5
5
  "main": "dist/product7-js.js",
6
6
  "module": "src/index.js",
@@ -952,6 +952,12 @@
952
952
  cursor: not-allowed;
953
953
  }
954
954
 
955
+ .liveChat-feedback-error {
956
+ font-size: var(--font-size-xs);
957
+ color: #ef4444;
958
+ margin-top: calc(var(--spacing-2) * -1);
959
+ }
960
+
955
961
  .liveChat-feedback-thankyou {
956
962
  display: flex;
957
963
  flex-direction: column;
@@ -963,9 +969,15 @@
963
969
  gap: var(--spacing-3);
964
970
  }
965
971
 
966
- .liveChat-feedback-thankyou-emoji {
967
- font-size: 48px;
968
- line-height: 1;
972
+ .liveChat-feedback-success-icon {
973
+ width: 56px;
974
+ height: 56px;
975
+ border-radius: 50%;
976
+ background: #037F0C;
977
+ display: flex;
978
+ align-items: center;
979
+ justify-content: center;
980
+ margin-bottom: var(--spacing-2);
969
981
  }
970
982
 
971
983
  .liveChat-feedback-thankyou h3 {
@@ -4,10 +4,10 @@ export async function getIpInfo() {
4
4
  if (_cached) return _cached;
5
5
 
6
6
  try {
7
- const res = await fetch('https://ipwho.is/');
7
+ const res = await fetch('https://ipapi.co/json/');
8
8
  if (!res.ok) return null;
9
9
  const data = await res.json();
10
- if (data.success) {
10
+ if (data.ip) {
11
11
  _cached = data;
12
12
  }
13
13
  return _cached;
@@ -149,6 +149,24 @@ export class LiveChatWidget extends BaseWidget {
149
149
  }
150
150
  }
151
151
 
152
+ async _handleSubmitFeedback({ title, message }) {
153
+ const payload = {
154
+ title: title || 'Feedback',
155
+ content: message,
156
+ board_id:
157
+ this.liveChatOptions.feedbackBoardName || this.sdk.config.boardName,
158
+ };
159
+
160
+ const response = await this.apiService.submitFeedback(payload);
161
+
162
+ this.sdk.eventBus.emit('feedback:submitted', {
163
+ widget: this,
164
+ feedback: response,
165
+ });
166
+
167
+ return response;
168
+ }
169
+
152
170
  _render() {
153
171
  const container = document.createElement('div');
154
172
  container.className = `liveChat-widget theme-${this.liveChatOptions.theme}`;
@@ -201,6 +219,7 @@ export class LiveChatWidget extends BaseWidget {
201
219
  onFeedbackClick:
202
220
  this.liveChatOptions.onFeedbackClick ||
203
221
  (this._feedbackWidget ? () => this._feedbackWidget.open() : null),
222
+ onSubmitFeedback: this._handleSubmitFeedback.bind(this),
204
223
  onArticleClick: this.liveChatOptions.onArticleClick,
205
224
  onChangelogClick: this.liveChatOptions.onChangelogClick,
206
225
  });
@@ -4,7 +4,6 @@ export class FeedbackFormView {
4
4
  this.options = options;
5
5
  this.element = null;
6
6
  this._isSubmitting = false;
7
- this._selectedRating = null;
8
7
  }
9
8
 
10
9
  render() {
@@ -34,6 +33,7 @@ export class FeedbackFormView {
34
33
  placeholder="Your feedback..."
35
34
  rows="5"
36
35
  ></textarea>
36
+ <span class="liveChat-feedback-error" style="display:none;"></span>
37
37
  <button class="liveChat-feedback-submit">Send feedback</button>
38
38
  </div>
39
39
  `;
@@ -49,9 +49,13 @@ export class FeedbackFormView {
49
49
  <span class="liveChat-feedback-title">Leave us feedback</span>
50
50
  </div>
51
51
  <div class="liveChat-feedback-thankyou">
52
- <span class="liveChat-feedback-thankyou-emoji">🙏</span>
53
- <h3>Thanks for your feedback!</h3>
54
- <p>We appreciate you taking the time to share your thoughts.</p>
52
+ <div class="liveChat-feedback-success-icon">
53
+ <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none" stroke="#ffffff" stroke-width="24" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 256 256">
54
+ <polyline points="216,72 96,192 40,136"/>
55
+ </svg>
56
+ </div>
57
+ <h3>Thank you!</h3>
58
+ <p>Your feedback has been submitted successfully.</p>
55
59
  <button class="liveChat-feedback-done-btn">Done</button>
56
60
  </div>
57
61
  `;
@@ -77,7 +81,36 @@ export class FeedbackFormView {
77
81
  });
78
82
  }
79
83
 
84
+ _showError(text) {
85
+ const errorEl = this.element.querySelector('.liveChat-feedback-error');
86
+ if (errorEl) {
87
+ errorEl.textContent = text;
88
+ errorEl.style.display = 'block';
89
+ }
90
+ }
91
+
92
+ _hideError() {
93
+ const errorEl = this.element.querySelector('.liveChat-feedback-error');
94
+ if (errorEl) {
95
+ errorEl.style.display = 'none';
96
+ }
97
+ }
98
+
80
99
  async _submit(title, message) {
100
+ this._hideError();
101
+
102
+ if (!title) {
103
+ this._showError('Please enter a title.');
104
+ this.element.querySelector('.liveChat-feedback-input').focus();
105
+ return;
106
+ }
107
+
108
+ if (!message) {
109
+ this._showError('Please enter your feedback message.');
110
+ this.element.querySelector('.liveChat-feedback-textarea').focus();
111
+ return;
112
+ }
113
+
81
114
  this._isSubmitting = true;
82
115
  const submitBtn = this.element.querySelector('.liveChat-feedback-submit');
83
116
  if (submitBtn) {
@@ -89,11 +122,16 @@ export class FeedbackFormView {
89
122
  if (this.options.onSubmitFeedback) {
90
123
  await this.options.onSubmitFeedback({ title, message });
91
124
  }
125
+ this._renderThankYou();
92
126
  } catch (e) {
93
127
  console.warn('[FeedbackFormView] Submit error:', e);
128
+ this._isSubmitting = false;
129
+ this._showError('Failed to submit feedback. Please try again.');
130
+ if (submitBtn) {
131
+ submitBtn.disabled = false;
132
+ submitBtn.textContent = 'Send feedback';
133
+ }
94
134
  }
95
-
96
- this._renderThankYou();
97
135
  }
98
136
 
99
137
  destroy() {