@designcrowd/library.brand-page 5.16.7 → 5.16.9

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 (46) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-wW2pGdd1.js → CreatedOnBrandCrowd-de-de-B6cjsGEo.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CBT4P6g7.js → CreatedOnBrandCrowd-en-us-DvRO5Sa0.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BnF7sK_H.js → CreatedOnBrandCrowd-es-es-DtVH8873.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DX9xl_Ha.js → CreatedOnBrandCrowd-fr-ca-D28gtzFz.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DX9xl_Ha.js → CreatedOnBrandCrowd-fr-fr-D28gtzFz.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-C0PsAWrw.js → CreatedOnBrandCrowd-pt-br-D10hKyH2.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-C0PsAWrw.js → CreatedOnBrandCrowd-pt-pt-D10hKyH2.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-OtYDdIlh.js → CreatedOnDcom-de-de-DMd-C-rQ.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-gV7rV48U.js → CreatedOnDcom-en-us-TclOYB4s.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CDnlL9E_.js → CreatedOnDcom-es-es-D2Q12HIf.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BvPz_3hN.js → CreatedOnDcom-fr-ca-CTRPkn9H.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-C8TnTmNZ.js → CreatedOnDcom-fr-fr-B0FpJam-.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-qB9SGJDP.js → CreatedOnDcom-pt-br-Cnf8RpjD.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-D9_4i33m.js → CreatedOnDcom-pt-pt-CDtpJcux.js} +1 -1
  15. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +1 -0
  16. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +18 -0
  17. package/lib/src/brand-page-maker/composables/useEventTracker.js +23 -0
  18. package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +1 -0
  19. package/lib/src/brand-page-maker/utils/mixpanel.util.js +29 -0
  20. package/lib/src/css/library.brand-page-brandCrowd.min.css +22 -22
  21. package/lib/src/css/library.brand-page-brandPage.min.css +22 -22
  22. package/lib/src/css/library.brand-page-designCom.min.css +22 -22
  23. package/lib/src/css/library.brand-page-preview.min.css +22 -22
  24. package/lib/src/index.mjs +1 -1
  25. package/lib/src/{lib-4panOoXa.js → lib-CRiA0WxA.js} +15730 -15646
  26. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -0
  27. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +1 -0
  28. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +1 -0
  29. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +4 -0
  30. package/lib/src/shared/content-settings/components/image-field/ImageField.mixin.js +3 -1
  31. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +1 -0
  32. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +1 -0
  33. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +1 -0
  34. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  35. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +1 -0
  36. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +1 -0
  37. package/package.json +1 -1
  38. package/src/brand-page-maker/composables/useEventTracker.ts +28 -0
  39. package/src/brand-page-maker/utils/mixpanel.util.ts +42 -0
  40. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +4 -0
  41. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -1
  42. package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +28 -17
  43. package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +62 -7
  44. package/src/shared/content-settings/components/image-field/ImageField.mixin.ts +4 -1
  45. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +3 -1
  46. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +3 -1
@@ -772,6 +772,7 @@ declare const _default: import("vue").DefineComponent<{}, {
772
772
  sendAddContentContinuationEvent: (continuation: string) => void;
773
773
  sendUpsellOfferEvent: (upsellType: string) => void;
774
774
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
775
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
775
776
  };
776
777
  externalEditor: import("@tiptap/vue-3").Editor;
777
778
  }, {
@@ -494,6 +494,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
494
494
  sendAddContentContinuationEvent: (continuation: string) => void;
495
495
  sendUpsellOfferEvent: (upsellType: string) => void;
496
496
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
497
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
497
498
  };
498
499
  }, {
499
500
  selectEventDebounceHandler: DebounceHandle | undefined;
@@ -811,6 +811,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
811
811
  generateText(): string;
812
812
  showGenerateText(): boolean;
813
813
  plainTextValue(): string;
814
+ ctaLocation(): string;
814
815
  }, {
815
816
  onFieldChanged(payload: UpdateItemValuePayload<unknown>): void;
816
817
  onFieldChangeLogo(): void;
@@ -12,6 +12,7 @@ import { commonTr } from '../../../../composables/useTranslate';
12
12
  import { getPlainTextFromRTE, replaceTextInRTE, } from '../../../../brand-page-maker/utils';
13
13
  import { isDefaultContentText } from '../../utils';
14
14
  import { useUiLogoSettingsStore } from '../../../logo-settings/store';
15
+ import { getCtaLocationFromFieldType } from '../../../../brand-page-maker/utils/mixpanel.util';
15
16
  const RTE_ALLOWED_SECTION_TYPES = [
16
17
  'banner-section',
17
18
  'text',
@@ -203,6 +204,9 @@ export default defineComponent({
203
204
  return '';
204
205
  return plainText;
205
206
  },
207
+ ctaLocation() {
208
+ return getCtaLocationFromFieldType(this.field.name, this.type);
209
+ },
206
210
  },
207
211
  watch: {
208
212
  fieldType() {
@@ -109,7 +109,9 @@ export default defineComponent({
109
109
  });
110
110
  },
111
111
  onRemove() {
112
- this.content.media = undefined;
112
+ if (this.content?.media) {
113
+ this.content.media = undefined;
114
+ }
113
115
  this.imgValue = '';
114
116
  this.imageUrl = '';
115
117
  },
@@ -198,6 +198,7 @@ declare const _default: import("vue").DefineComponent<{}, {
198
198
  sendAddContentContinuationEvent: (continuation: string) => void;
199
199
  sendUpsellOfferEvent: (upsellType: string) => void;
200
200
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
201
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
201
202
  };
202
203
  makerFonts: import("vue").ComputedRef<{
203
204
  id: string;
@@ -4709,6 +4709,7 @@ declare const _default: import("vue").DefineComponent<{}, {
4709
4709
  sendAddContentContinuationEvent: (continuation: string) => void;
4710
4710
  sendUpsellOfferEvent: (upsellType: string) => void;
4711
4711
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
4712
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
4712
4713
  };
4713
4714
  }, {
4714
4715
  isDeleteModalVisible: boolean;
@@ -434,6 +434,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
434
434
  sendAddContentContinuationEvent: (continuation: string) => void;
435
435
  sendUpsellOfferEvent: (upsellType: string) => void;
436
436
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
437
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
437
438
  };
438
439
  }, {
439
440
  purchasedDomains: UserDomainName[];
@@ -37,6 +37,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
37
37
  sendAddContentContinuationEvent: (continuation: string) => void;
38
38
  sendUpsellOfferEvent: (upsellType: string) => void;
39
39
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
40
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
40
41
  };
41
42
  }, {}, {}, {
42
43
  onTabSelected(tabName: string): void;
@@ -879,6 +879,7 @@ declare const _default: import("vue").DefineComponent<{}, {
879
879
  sendAddContentContinuationEvent: (continuation: string) => void;
880
880
  sendUpsellOfferEvent: (upsellType: string) => void;
881
881
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
882
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
882
883
  };
883
884
  }, {
884
885
  styleThemeKeys: Readonly<{
@@ -580,6 +580,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
580
580
  sendAddContentContinuationEvent: (continuation: string) => void;
581
581
  sendUpsellOfferEvent: (upsellType: string) => void;
582
582
  sendUpsellOfferActionEvent: (upsellType: string, action: string) => void;
583
+ sendGenerateTextContinuationEvent: (cta_location: string, continuation: string | null) => void;
583
584
  };
584
585
  }, {
585
586
  tabs: string[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "5.16.7",
4
+ "version": "5.16.9",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -53,6 +53,11 @@ export const EVENTS = {
53
53
  WEBSITE_MAKER_UPSELL_ACTION: 'website_maker_upsell_action',
54
54
  WEBSITE_MAKER_SWITCH_LOGO: 'website_maker_switch_logo',
55
55
  WEBSITE_MAKER_SWITCH_LOGO_MODAL: 'website_maker_switch_logo_modal',
56
+ WEBSITE_MAKER_AI_GENERATE_TEXT: 'website_maker_ai_generate_text',
57
+ WEBSITE_MAKER_AI_REGENERATE_TEXT: 'website_maker_ai_regenerate_text',
58
+ WEBSITE_MAKER_AI_SEND_PROMPT: 'website_maker_ai_send_prompt',
59
+ WEBSITE_MAKER_AI_COPY_RESPONSE: 'website_maker_ai_copy_response',
60
+ WEBSITE_MAKER_AI_STOP_GENERATION: 'website_maker_ai_stop_generation',
56
61
  };
57
62
 
58
63
  export const SELECT_LOCATIONS = {
@@ -76,6 +81,15 @@ export const UPGRADE_CTA_LOCATIONS = {
76
81
  GOOGLE_ADSENSE: 'google_adsense',
77
82
  };
78
83
 
84
+ export const GENERATE_AI_TEXT_CTA_LOCATIONS = {
85
+ BANNER_DESCRIPTION: 'banner_description',
86
+ BANNER_TITLE: 'banner_title',
87
+ ABOUT_TITLE: 'about_title',
88
+ ABOUT_PARAGRAPH: 'about_paragraph',
89
+ TEXT_ITEM: 'text_item',
90
+ TESTIMONIAL_ITEM: 'testimonial_item',
91
+ };
92
+
79
93
  export const TRIGGER_TYPE = {
80
94
  AUTOMATIC: 'automatic',
81
95
  USER_TRIGGERED: 'user_triggered',
@@ -90,6 +104,11 @@ export const PUBLISH_MODAL_CONTINUATION_EVENTS = {
90
104
  VIEW_WEBSITE: 'view_website',
91
105
  };
92
106
 
107
+ export const GENERATE_TEXT_CONTINUATION_EVENTS = {
108
+ USE_TEXT: 'use_text',
109
+ EXIT: 'exit',
110
+ };
111
+
93
112
  export const PUBLISH_OPTION_MODAL_CONTINUATION_EVENTS = {
94
113
  PREMIUM: 'premium',
95
114
  EXIT: 'exit',
@@ -266,6 +285,15 @@ const useEventTracker = () => {
266
285
  action,
267
286
  });
268
287
  },
288
+ sendGenerateTextContinuationEvent: (
289
+ cta_location: string,
290
+ continuation: string | null,
291
+ ) => {
292
+ _publishEvent(EVENTS.WEBSITE_MAKER_AI_GENERATE_TEXT, {
293
+ cta_location,
294
+ continuation,
295
+ });
296
+ },
269
297
  };
270
298
  };
271
299
 
@@ -0,0 +1,42 @@
1
+ import { GENERATE_AI_TEXT_CTA_LOCATIONS } from '../composables/useEventTracker';
2
+
3
+ export const getCtaLocationFromFieldType = (
4
+ fieldType: string,
5
+ sectionType?: string,
6
+ ): string => {
7
+ if (fieldType === 'text') {
8
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.TEXT_ITEM;
9
+ }
10
+
11
+ if (fieldType === 'testimonials') {
12
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.TESTIMONIAL_ITEM;
13
+ }
14
+
15
+ if (sectionType === 'banner-section') {
16
+ if (fieldType === 'description') {
17
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.BANNER_DESCRIPTION;
18
+ }
19
+
20
+ if (fieldType === 'title') {
21
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.BANNER_TITLE;
22
+ }
23
+ }
24
+
25
+ if (sectionType === 'about-section') {
26
+ if (fieldType === 'title') {
27
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.ABOUT_TITLE;
28
+ }
29
+
30
+ if (fieldType === 'paragraph') {
31
+ return GENERATE_AI_TEXT_CTA_LOCATIONS.ABOUT_PARAGRAPH;
32
+ }
33
+ }
34
+
35
+ // Fallback: try to match directly with field type
36
+ // This handles cases where fieldType might already be in the correct format
37
+ const matchingLocation = Object.values(GENERATE_AI_TEXT_CTA_LOCATIONS).find(
38
+ (location) => location === fieldType,
39
+ );
40
+
41
+ return matchingLocation || fieldType;
42
+ };
@@ -30,6 +30,7 @@ import {
30
30
  } from '../../../../brand-page-maker/utils';
31
31
  import { isDefaultContentText } from '../../utils';
32
32
  import { useUiLogoSettingsStore } from '../../../logo-settings/store';
33
+ import { getCtaLocationFromFieldType } from '../../../../brand-page-maker/utils/mixpanel.util';
33
34
 
34
35
  const RTE_ALLOWED_SECTION_TYPES = [
35
36
  'banner-section',
@@ -252,6 +253,9 @@ export default defineComponent({
252
253
 
253
254
  return plainText;
254
255
  },
256
+ ctaLocation(): string {
257
+ return getCtaLocationFromFieldType(this.field.name, this.type);
258
+ },
255
259
  },
256
260
  watch: {
257
261
  fieldType() {
@@ -28,7 +28,7 @@
28
28
  :id="`${id}-${field.name}`"
29
29
  :existing-text="plainTextValue"
30
30
  :is-design-com="isDesignCom"
31
- :field-type="field.name"
31
+ :cta-location="ctaLocation"
32
32
  @capture-snapshot="onCaptureSnapshot"
33
33
  @on-use-text="onUseGeneratedText"
34
34
  />
@@ -15,8 +15,7 @@
15
15
  :is-visible="generateTextModalVisible"
16
16
  :existing-text="props.existingText"
17
17
  :is-design-com="props.isDesignCom"
18
- :snapshot-base64="snapshotBase64"
19
- :field-type="props.fieldType"
18
+ :cta-location="props.ctaLocation"
20
19
  @on-close="onCloseGenerateTextModal"
21
20
  @on-use-text="handleUseGeneratedText"
22
21
  />
@@ -33,18 +32,22 @@ import {
33
32
  useSnapshotStore,
34
33
  } from '../../../../brand-page-maker/stores';
35
34
  import type { AbTestResult } from '../../../../brand-page/models/brand-page-context.model';
35
+ import {
36
+ EVENTS,
37
+ GENERATE_TEXT_CONTINUATION_EVENTS,
38
+ useEventTracker,
39
+ } from '../../../../brand-page-maker/composables/useEventTracker';
36
40
 
37
41
  interface Props {
38
42
  id: string;
39
43
  existingText: string;
40
44
  isDesignCom?: boolean;
41
45
  captureSnapshotDelay?: number;
42
- fieldType?: string;
46
+ ctaLocation: string;
43
47
  }
44
48
 
45
49
  const props = withDefaults(defineProps<Props>(), {
46
50
  isDesignCom: false,
47
- fieldType: 'text',
48
51
  });
49
52
 
50
53
  const emit = defineEmits<{
@@ -52,10 +55,10 @@ const emit = defineEmits<{
52
55
  'capture-snapshot': [];
53
56
  }>();
54
57
 
55
- const snapshotStore = useSnapshotStore();
56
58
  const brandPageContainerStore = useBrandPageContainerStore();
59
+ const eventTracker = useEventTracker();
60
+ const snapshotStore = useSnapshotStore();
57
61
 
58
- const snapshotBase64 = computed(() => snapshotStore.snapshotBase64);
59
62
  const abTests = computed(() => brandPageContainerStore.abTests);
60
63
 
61
64
  const showButton = computed(() => {
@@ -69,27 +72,35 @@ const showButton = computed(() => {
69
72
  const generateTextModalVisible = ref(false);
70
73
  const generateText = commonTr('generateText');
71
74
 
72
- const onShowGenerateModal = async () => {
73
- emit('capture-snapshot');
75
+ const onShowGenerateModal = () => {
76
+ generateTextModalVisible.value = true;
74
77
 
75
- const maxWaitTime = 5000; // 5 seconds max
76
- const pollInterval = 50; // Check every 50ms
77
- let elapsedTime = 0;
78
+ eventTracker.sendWebsiteEvent({
79
+ eventName: EVENTS.WEBSITE_MAKER_AI_GENERATE_TEXT,
80
+ eventProps: {
81
+ cta_location: props.ctaLocation,
82
+ continuation: null,
83
+ },
84
+ });
78
85
 
79
- while (!snapshotBase64.value && elapsedTime < maxWaitTime) {
80
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
81
- elapsedTime += pollInterval;
82
- }
86
+ snapshotStore.clearSnapshot();
83
87
 
84
- generateTextModalVisible.value = true;
88
+ setTimeout(() => {
89
+ emit('capture-snapshot');
90
+ }, 50);
85
91
  };
86
92
 
87
93
  const onCloseGenerateTextModal = () => {
88
94
  generateTextModalVisible.value = false;
95
+
96
+ eventTracker.sendGenerateTextContinuationEvent(
97
+ props.ctaLocation,
98
+ GENERATE_TEXT_CONTINUATION_EVENTS.EXIT,
99
+ );
89
100
  };
90
101
 
91
102
  const handleUseGeneratedText = (generatedText: string) => {
92
103
  emit('on-use-text', generatedText);
93
- onCloseGenerateTextModal();
104
+ generateTextModalVisible.value = false;
94
105
  };
95
106
  </script>
@@ -162,13 +162,18 @@ import {
162
162
  commonTr,
163
163
  } from '../../../../composables/useTranslate';
164
164
  import { getInstance as getDesignTemplateClient } from '../../../../clients/design-template-client';
165
+ import {
166
+ EVENTS,
167
+ GENERATE_TEXT_CONTINUATION_EVENTS,
168
+ useEventTracker,
169
+ } from '../../../../brand-page-maker/composables/useEventTracker';
170
+ import { useSnapshotStore } from '../../../../brand-page-maker/stores';
165
171
 
166
172
  interface Props {
167
173
  isVisible: boolean;
168
174
  existingText?: string;
169
- snapshotBase64?: string | null;
170
175
  isDesignCom?: boolean;
171
- fieldType?: string;
176
+ ctaLocation: string;
172
177
  }
173
178
 
174
179
  const props = withDefaults(defineProps<Props>(), {
@@ -190,9 +195,13 @@ const data = reactive({
190
195
  promptError: '',
191
196
  });
192
197
 
198
+ const eventTracker = useEventTracker();
193
199
  const textareaRef = ref<HTMLTextAreaElement | null>(null);
194
200
  const MAX_PROMPT_LENGTH = 500;
195
201
 
202
+ const snapshotStore = useSnapshotStore();
203
+ const snapshotBase64 = computed(() => snapshotStore.snapshotBase64);
204
+
196
205
  // Auto-resize textarea
197
206
  const resizeTextarea = () => {
198
207
  if (textareaRef.value) {
@@ -301,6 +310,13 @@ const typeText = (fullText: string) => {
301
310
  const copyToClipboard = async () => {
302
311
  if (!data.response) return;
303
312
 
313
+ eventTracker.sendWebsiteEvent({
314
+ eventName: EVENTS.WEBSITE_MAKER_AI_COPY_RESPONSE,
315
+ eventProps: {
316
+ cta_location: props.ctaLocation,
317
+ },
318
+ });
319
+
304
320
  try {
305
321
  await navigator.clipboard.writeText(data.response);
306
322
  data.isCopied = true;
@@ -317,21 +333,44 @@ const copyToClipboard = async () => {
317
333
  const onUseText = () => {
318
334
  if (!data.response) return;
319
335
 
336
+ eventTracker.sendGenerateTextContinuationEvent(
337
+ props.ctaLocation,
338
+ GENERATE_TEXT_CONTINUATION_EVENTS.USE_TEXT,
339
+ );
340
+
320
341
  emit('on-use-text', data.response);
321
342
  onClose();
322
343
  };
323
344
 
324
345
  const onStopGeneration = () => {
346
+ eventTracker.sendWebsiteEvent({
347
+ eventName: EVENTS.WEBSITE_MAKER_AI_STOP_GENERATION,
348
+ eventProps: {
349
+ cta_location: props.ctaLocation,
350
+ },
351
+ });
325
352
  stopGeneration();
326
353
  data.response = generateAiModalTr('generationStopped');
327
354
  };
328
355
  const onRegeneratePrompt = () => {
329
356
  if (data.lastPromptSent) {
357
+ eventTracker.sendWebsiteEvent({
358
+ eventName: EVENTS.WEBSITE_MAKER_AI_REGENERATE_TEXT,
359
+ eventProps: {
360
+ cta_location: props.ctaLocation,
361
+ },
362
+ });
330
363
  onSendPrompt(data.lastPromptSent);
331
364
  }
332
365
  };
333
366
 
334
367
  const onSendButtonClick = () => {
368
+ eventTracker.sendWebsiteEvent({
369
+ eventName: EVENTS.WEBSITE_MAKER_AI_SEND_PROMPT,
370
+ eventProps: {
371
+ cta_location: props.ctaLocation,
372
+ },
373
+ });
335
374
  onSendPrompt();
336
375
  };
337
376
 
@@ -354,11 +393,21 @@ const onSendPrompt = async (customPrompt?: string) => {
354
393
  clearTypingInterval();
355
394
 
356
395
  try {
396
+ const maxWaitTime = 5000;
397
+ const pollInterval = 50;
398
+ let elapsedTime = 0;
399
+
400
+ // Wait for snapshot to be captured (triggered by button component)
401
+ while (!snapshotBase64.value && elapsedTime < maxWaitTime) {
402
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
403
+ elapsedTime += pollInterval;
404
+ }
405
+
357
406
  const client = getDesignTemplateClient();
358
407
  const result = await client.generateText(
359
408
  promptToSend,
360
409
  props.existingText ?? '',
361
- props.snapshotBase64 || undefined,
410
+ snapshotBase64.value || undefined,
362
411
  );
363
412
 
364
413
  // Check if generation was stopped before setting response
@@ -387,10 +436,10 @@ const onSendPrompt = async (customPrompt?: string) => {
387
436
  }
388
437
  };
389
438
 
390
- // Generate default prompt based on field type
439
+ // Generate default prompt based on CTA location
391
440
  const getDefaultPrompt = (): string => {
392
- const fieldType = props.fieldType || 'text';
393
- return `Improve this ${fieldType}`;
441
+ const locationLabel = props.ctaLocation.replace(/_/g, ' ');
442
+ return `Improve this ${locationLabel}`;
394
443
  };
395
444
 
396
445
  // Auto-generate text when modal opens if there's existing text
@@ -404,6 +453,12 @@ watch(
404
453
  data.lastPromptSent = '';
405
454
 
406
455
  if (props.existingText && props.existingText.trim()) {
456
+ eventTracker.sendWebsiteEvent({
457
+ eventName: EVENTS.WEBSITE_MAKER_AI_SEND_PROMPT,
458
+ eventProps: {
459
+ cta_location: props.ctaLocation,
460
+ },
461
+ });
407
462
  const defaultPrompt = getDefaultPrompt();
408
463
  onSendPrompt(defaultPrompt);
409
464
  }
@@ -415,7 +470,7 @@ watch(
415
470
  data.isTyping = false;
416
471
  }
417
472
  },
418
- { flush: 'sync' }, // Execute synchronously to prevent race conditions
473
+ { flush: 'sync' },
419
474
  );
420
475
 
421
476
  onUnmounted(clearTypingInterval);
@@ -122,7 +122,10 @@ export default defineComponent({
122
122
  },
123
123
 
124
124
  onRemove() {
125
- this.content.media = undefined;
125
+ if (this.content?.media) {
126
+ this.content.media = undefined;
127
+ }
128
+
126
129
  this.imgValue = '';
127
130
  this.imageUrl = '';
128
131
  },
@@ -21,7 +21,7 @@
21
21
  :id="`${id}-${option.index}`"
22
22
  :existing-text="getPlainTextValue(option.index)"
23
23
  :is-design-com="isDesignCom"
24
- field-type="testimonials"
24
+ :cta-location="getCtaLocationFromFieldType('testimonials')"
25
25
  @capture-snapshot="onCaptureSnapshot"
26
26
  @on-use-text="(text) => onUseGeneratedText(text, option.index)"
27
27
  />
@@ -204,6 +204,7 @@ import TextareaField from '../../../content-settings/components/textarea-field/T
204
204
  import ColorReplacementsField from '../color-replacements-field/ColorReplacementsField.vue';
205
205
  import GenerateAiButton from '../generate-ai-button/GenerateAiButton.vue';
206
206
  import { testimonialItemsFieldTr } from '../../../../composables/useTranslate';
207
+ import { getCtaLocationFromFieldType } from '../../../../brand-page-maker/utils/mixpanel.util';
207
208
  import PersonalisationOverrideField from '../../../content-settings/components/personalisation-override-field/PersonalisationOverrideField.vue';
208
209
 
209
210
  export default {
@@ -221,6 +222,7 @@ export default {
221
222
  setup() {
222
223
  return {
223
224
  testimonialItemsFieldTr,
225
+ getCtaLocationFromFieldType,
224
226
  };
225
227
  },
226
228
  };
@@ -21,7 +21,7 @@
21
21
  :id="`${id}-${option.index}`"
22
22
  :existing-text="getPlainTextValue(option.index)"
23
23
  :is-design-com="isDesignCom"
24
- field-type="text"
24
+ :cta-location="getCtaLocationFromFieldType('text')"
25
25
  @capture-snapshot="onCaptureSnapshot"
26
26
  @on-use-text="(text) => onUseGeneratedText(text, option.index)"
27
27
  />
@@ -97,6 +97,7 @@ import {
97
97
  textItemsFieldTr,
98
98
  } from '../../../../composables/useTranslate';
99
99
  import PersonalisationOverrideField from '../../../content-settings/components/personalisation-override-field/PersonalisationOverrideField.vue';
100
+ import { getCtaLocationFromFieldType } from '../../../../brand-page-maker/utils/mixpanel.util';
100
101
 
101
102
  export default {
102
103
  components: {
@@ -112,6 +113,7 @@ export default {
112
113
  return {
113
114
  commonTr,
114
115
  textItemsFieldTr,
116
+ getCtaLocationFromFieldType,
115
117
  };
116
118
  },
117
119
  };