@gudhub/ssg-web-components-library 1.0.105 → 1.0.107

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": "@gudhub/ssg-web-components-library",
3
- "version": "1.0.105",
3
+ "version": "1.0.107",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -32,7 +32,7 @@ class CategoryBanner extends GHComponent {
32
32
  const items = await gudhub.getItems(ids.appId);
33
33
  const item = items.find(item => item.item_id == ids.itemId);
34
34
 
35
- let description = await fetch(`https://gudhub.com/userdata/${ids.appId}/${item.fields.find(field => field.field_id == window.getConfig().chapters.blog.description_field_id).field_value}.html?t=${new Date().getTime()}`);
35
+ let description = await fetch(`https://app.gudhub.com/userdata/${ids.appId}/${item.fields.find(field => field.field_id == window.getConfig().chapters.blog.description_field_id).field_value}.html?t=${new Date().getTime()}`);
36
36
  description = await description.text();
37
37
 
38
38
  let div = document.createElement('div');
@@ -111,7 +111,7 @@ class CommentsComponent extends GHComponent {
111
111
 
112
112
  if (comment.name && comment.text) {
113
113
  const { api_app_id } = window.getConfig().chapters.blog;
114
- const response = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/add-comment`, {
114
+ const response = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/add-comment`, {
115
115
  method: 'POST',
116
116
  headers: {
117
117
  'Content-Type': 'application/json'
@@ -309,7 +309,7 @@ class PostsTemplate extends GHComponent {
309
309
 
310
310
  const { api_app_id } = window.getConfig().chapters.blog;
311
311
 
312
- const response = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/articles`);
312
+ const response = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/articles`);
313
313
  const data = await response.json();
314
314
  let articles = data.articlesAndComments.articles;
315
315
  let comments = data.articlesAndComments.comments;
@@ -334,7 +334,7 @@ class PostsTemplate extends GHComponent {
334
334
  }
335
335
 
336
336
  if (this.type === 'category') {
337
- const categoriesResponse = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/categories`)
337
+ const categoriesResponse = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/categories`)
338
338
  let categories = await categoriesResponse.json();
339
339
  categories = categories.categories;
340
340
  let category = window.location.pathname;
@@ -364,7 +364,7 @@ class PostsTemplate extends GHComponent {
364
364
  return articles;
365
365
  }
366
366
  if (this.type === 'author') {
367
- const authorsResponse = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/authors`)
367
+ const authorsResponse = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/authors`)
368
368
  let authors = await authorsResponse.json();
369
369
  authors = authors.authors;
370
370
  const author = window.location.pathname;
@@ -409,7 +409,7 @@ class PostsTemplate extends GHComponent {
409
409
  async fetchIntro(posts) {
410
410
  const { api_app_id, intro_field_id, app_id } = window.getConfig().chapters.blog;
411
411
  const fetchData = async (index, item_id) => {
412
- const responseIntro = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/get-intro?app_id=${app_id}&item_id=${item_id}&element_id=${intro_field_id}`);
412
+ const responseIntro = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/get-intro?app_id=${app_id}&item_id=${item_id}&element_id=${intro_field_id}`);
413
413
  const dataIntro = await responseIntro.json();
414
414
  let introItems = JSON.parse(dataIntro.data).blocks[0].data;
415
415
  posts[index].intro = introItems;
@@ -473,7 +473,7 @@ class PostsTemplate extends GHComponent {
473
473
  if (!articles[0].author_slug) {
474
474
 
475
475
  const { api_app_id } = window.getConfig().chapters.blog;
476
- const authorsResponse = await fetch(`https://gudhub.com/api/services/prod/api/${api_app_id}/authors`)
476
+ const authorsResponse = await fetch(`https://app.gudhub.com/api/services/api/${api_app_id}/authors`)
477
477
  authors = await authorsResponse.json();
478
478
  authors = authors.authors;
479
479
  }
@@ -7,6 +7,10 @@ import { checkInputsValidations } from './inputsValidation.js';
7
7
  let recaptchaPromise = null;
8
8
 
9
9
  function loadRecaptcha(siteKey) {
10
+ if (!siteKey) {
11
+ return Promise.reject(new Error('reCAPTCHA site key is missing'));
12
+ }
13
+
10
14
  if (window.grecaptcha) return Promise.resolve(window.grecaptcha);
11
15
 
12
16
  if (recaptchaPromise) return recaptchaPromise;
@@ -19,10 +23,10 @@ function loadRecaptcha(siteKey) {
19
23
 
20
24
  script.onload = () => {
21
25
  if (window.grecaptcha) resolve(window.grecaptcha);
22
- else reject('grecaptcha not available');
26
+ else reject(new Error('grecaptcha not available'));
23
27
  };
24
28
 
25
- script.onerror = reject;
29
+ script.onerror = () => reject(new Error('Failed to load reCAPTCHA script'));
26
30
 
27
31
  document.head.appendChild(script);
28
32
  });
@@ -68,6 +72,8 @@ class GetInTouchForm extends GHComponent {
68
72
  this.initConfig(this.config);
69
73
  super.render(html);
70
74
  this.attachEventListeners();
75
+
76
+ loadRecaptcha(this.recaptcha_site_key).catch(console.error);
71
77
  }
72
78
 
73
79
  attachEventListeners() {
@@ -103,6 +109,10 @@ class GetInTouchForm extends GHComponent {
103
109
  }
104
110
 
105
111
  async getRecaptchaToken(action = 'submit') {
112
+ if (!this.recaptcha_site_key) {
113
+ throw new Error('reCAPTCHA site key is missing');
114
+ }
115
+
106
116
  const grecaptcha = await loadRecaptcha(this.recaptcha_site_key);
107
117
 
108
118
  return new Promise((resolve, reject) => {
@@ -126,7 +136,7 @@ class GetInTouchForm extends GHComponent {
126
136
  try {
127
137
  const token = await this.getRecaptchaToken();
128
138
 
129
- await this.fetchExample(token);
139
+ await this.verifyRecaptcha(token);
130
140
 
131
141
  this.handleSuccessFormValidation(form, token);
132
142
 
@@ -158,7 +168,6 @@ class GetInTouchForm extends GHComponent {
158
168
  window.dispatchEvent(new CustomEvent('submitForm', { detail: { formDataObj } }));
159
169
 
160
170
  this.isFormSubmitted = true;
161
- this.removeLoader();
162
171
  };
163
172
 
164
173
  inputsValidation = async (form) => {
@@ -166,16 +175,25 @@ class GetInTouchForm extends GHComponent {
166
175
  return checkInputsValidations(inputs);
167
176
  }
168
177
 
169
- fetchExample = (recaptchaToken) => {
170
- const isSuccess = true;
178
+ verifyRecaptcha = async (recaptchaToken) => {
179
+ const response = await fetch('/api/verify-recaptcha', {
180
+ method: 'POST',
181
+ headers: {
182
+ 'Content-Type': 'application/json'
183
+ },
184
+ body: JSON.stringify({
185
+ token: recaptchaToken,
186
+ action: 'submit'
187
+ })
188
+ });
171
189
 
172
- return new Promise((resolve, reject) => {
173
- console.log('reCAPTCHA token:', recaptchaToken);
190
+ const data = await response.json();
174
191
 
175
- setTimeout(() => {
176
- isSuccess ? resolve() : reject();
177
- }, 2000);
178
- });
192
+ if (!response.ok || !data.success) {
193
+ throw new Error(data?.error || 'reCAPTCHA verification failed');
194
+ }
195
+
196
+ return data;
179
197
  }
180
198
 
181
199
  createDataObject(form, placement, recaptchaToken) {
@@ -215,15 +233,20 @@ class GetInTouchForm extends GHComponent {
215
233
  setTimeout(() => btn.disabled = false, 500);
216
234
  }
217
235
 
218
- showSuccess({email, phone}) {
219
- if (email) {
220
- this.querySelector('.check_entity').classList.add('provided');
221
- this.getElementsByClassName('email')[0].innerText = email;
236
+ showSuccess({ email, phone }) {
237
+ const emailEntity = this.querySelector('.check_entity');
238
+ const phoneEntity = this.querySelector('.phone_entity');
239
+ const emailEl = this.getElementsByClassName('email')[0];
240
+ const phoneEl = this.getElementsByClassName('phone')[0];
241
+
242
+ if (email && emailEntity && emailEl) {
243
+ emailEntity.classList.add('provided');
244
+ emailEl.innerText = email;
222
245
  }
223
246
 
224
- if (phone) {
225
- this.querySelector('.phone_entity').classList.add('provided');
226
- this.getElementsByClassName('phone')[0].innerText = phone;
247
+ if (phone && phoneEntity && phoneEl) {
248
+ phoneEntity.classList.add('provided');
249
+ phoneEl.innerText = phone;
227
250
  }
228
251
 
229
252
  this.classList.add('success');
@@ -234,9 +257,16 @@ class GetInTouchForm extends GHComponent {
234
257
  }
235
258
 
236
259
  hideSuccess() {
237
- this.getElementsByClassName('email')[0].innerText = '';
238
- this.getElementsByClassName('phone')[0].innerText = '';
239
- this.querySelector('.phone_entity').classList.remove('provided');
260
+ const emailEl = this.getElementsByClassName('email')[0];
261
+ const phoneEl = this.getElementsByClassName('phone')[0];
262
+ const phoneEntity = this.querySelector('.phone_entity');
263
+ const emailEntity = this.querySelector('.check_entity');
264
+
265
+ if (emailEl) emailEl.innerText = '';
266
+ if (phoneEl) phoneEl.innerText = '';
267
+ if (phoneEntity) phoneEntity.classList.remove('provided');
268
+ if (emailEntity) emailEntity.classList.remove('provided');
269
+
240
270
  this.classList.remove('success');
241
271
  }
242
272
 
@@ -42,7 +42,7 @@ We have two different ways to use this component:
42
42
  | `alt` | Alternative text for the image | `string`<br>`"Description of image"` |
43
43
  | `title` | Image title (shown as tooltip) | `string`<br>`"My Image Title"` |
44
44
  | `lazyload` | Enables native browser lazy loading (`loading="lazy"`) | `boolean` (just include the attribute) |
45
- | `data-url` | Remote image URL | `string`<br>`https://gudhub.com/userdata/29883/1083204.jpg` |
45
+ | `data-url` | Remote image URL | `string`<br>`https://app.gudhub.com/userdata/29883/1083204.jpg` |
46
46
  | `data-rerender` | Enables client-side rerendering after SSR *(currently not working❗❗❗)* | `boolean` (just include the attribute) |
47
47
  | `width` | Image width | `string`<br>`"300"` |
48
48
  | `height` | Image height | `string`<br>`"200"` |
@@ -104,7 +104,7 @@ class MetaTag extends GHComponent {
104
104
  let slugValue = item.fields.find(findedField => findedField.field_id == slugId).field_value;
105
105
  let imageValue = (!slugValue.includes('/blog/') && !slugValue.includes('/service-areas/') && !slugValue.includes('/courses/')) ? item.fields.find(findedField => findedField.field_id == imageUrl).field_value : false;
106
106
 
107
- // value = isNaN(value) ? value : await this.getContent(`https://gudhub.com/userdata/${window.getConfig().chapters[chapter].app_id}/${value}.html`);
107
+ // value = isNaN(value) ? value : await this.getContent(`https://app.gudhub.com/userdata/${window.getConfig().chapters[chapter].app_id}/${value}.html`);
108
108
  titleValue = isNaN(titleValue) ? titleValue : await this.getContent(`https://app.gudhub.com/userdata/${window.getConfig().chapters[chapter].app_id}/${titleValue}.html`);
109
109
  descriptionValue = isNaN(descriptionValue) ? descriptionValue : await this.getContent(`https://app.gudhub.com/userdata/${window.getConfig().chapters[chapter].app_id}/${descriptionValue}.html`);
110
110
  slugValue = isNaN(slugValue) ? slugValue : await this.getContent(`https://app.gudhub.com/userdata/${window.getConfig().chapters[chapter].app_id}/${slugValue}.html`);