@designcrowd/library.brand-page 5.17.28 → 5.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-CJZpKPNH.js → CreatedOnBrandCrowd-de-de-xmkupPus.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DkIa7iEb.js → CreatedOnBrandCrowd-en-us-Ck7EdTtb.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CE2p6XHz.js → CreatedOnBrandCrowd-es-es-BC8sJuDH.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BBjOZS3M.js → CreatedOnBrandCrowd-fr-ca-CN-UBe1q.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BBjOZS3M.js → CreatedOnBrandCrowd-fr-fr-CN-UBe1q.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-br-CajQyNkx.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-pt-CajQyNkx.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CFzDqfCb.js → CreatedOnDcom-de-de-BRCNMmDq.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-C2jIPBDY.js → CreatedOnDcom-en-us-BzQDtZhc.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-qejpzqho.js → CreatedOnDcom-es-es-D-qAM4Cd.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DMO9Ld7K.js → CreatedOnDcom-fr-ca-CZ1irFOc.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-BFWN9qTP.js → CreatedOnDcom-fr-fr-Gb5BCF0N.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CneD3ghF.js → CreatedOnDcom-pt-br-CAQV0q6o.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Cg1B7s0o.js → CreatedOnDcom-pt-pt-D6tQdQFh.js} +1 -1
  15. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
  16. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
  17. package/lib/src/brand-page/models/brand-page-context.model.js +1 -11
  18. package/lib/src/brand-page/models/index.d.ts +1 -0
  19. package/lib/src/brand-page/models/index.js +1 -0
  20. package/lib/src/brand-page/utils/color.util.js +23 -3
  21. package/lib/src/brand-page/utils/raygun.util.d.ts +5 -1
  22. package/lib/src/brand-page/utils/raygun.util.js +7 -2
  23. package/lib/src/brand-page/utils/svg-color.util.js +1 -2
  24. package/lib/src/brand-page/utils/view-model.util.js +1 -1
  25. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -31
  26. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -2
  27. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -31
  28. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
  29. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -28
  30. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -28
  31. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -28
  32. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -28
  33. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -28
  34. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -28
  35. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +35 -0
  36. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +108 -0
  37. package/lib/src/brand-page-maker/composables/ai-chat/{useAiChat.d.ts → types.d.ts} +5 -13
  38. package/lib/src/brand-page-maker/composables/ai-chat/types.js +1 -0
  39. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +19 -0
  40. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  41. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +1 -1
  42. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +488 -82
  43. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +5 -5
  44. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +6 -16
  45. package/lib/src/brand-page-maker/composables/useEventTracker.js +19 -21
  46. package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +0 -1
  47. package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -15
  48. package/lib/src/brand-page-maker/convertors/image-aspect-ratio.convertor.js +2 -2
  49. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  50. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +30660 -0
  51. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.js +34 -0
  52. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +1 -1
  53. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -28
  54. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
  55. package/lib/src/brand-page-maker/stores/index.d.ts +1 -1
  56. package/lib/src/brand-page-maker/stores/index.js +1 -1
  57. package/lib/src/brand-page-maker/stores/user/user-store.js +0 -1
  58. package/lib/src/bundled-translations-CnareLWC.js +175 -0
  59. package/lib/src/bundled-translations.de-DE-2Ys7epLO.js +175 -0
  60. package/lib/src/bundled-translations.es-ES-Cjp-G8rT.js +175 -0
  61. package/lib/src/bundled-translations.fr-CA-CsaW4Oae.js +175 -0
  62. package/lib/src/bundled-translations.fr-FR-DIT2dd8J.js +175 -0
  63. package/lib/src/bundled-translations.pt-BR-BamoBpDW.js +175 -0
  64. package/lib/src/bundled-translations.pt-PT-C9A4hY_e.js +175 -0
  65. package/lib/src/bundles/bundled-translations.de-DE.json +1 -20
  66. package/lib/src/bundles/bundled-translations.es-ES.json +1 -20
  67. package/lib/src/bundles/bundled-translations.fr-CA.json +1 -20
  68. package/lib/src/bundles/bundled-translations.fr-FR.json +1 -20
  69. package/lib/src/bundles/bundled-translations.json +1 -20
  70. package/lib/src/bundles/bundled-translations.pt-BR.json +1 -20
  71. package/lib/src/bundles/bundled-translations.pt-PT.json +1 -20
  72. package/lib/src/clients/ai-assistant-client.d.ts +30 -29
  73. package/lib/src/clients/ai-assistant-client.js +16 -16
  74. package/lib/src/clients/design-template-client.d.ts +0 -2
  75. package/lib/src/clients/design-template-client.js +0 -38
  76. package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
  77. package/lib/src/composables/useTranslate.d.ts +2 -1
  78. package/lib/src/composables/useTranslate.js +2 -1
  79. package/lib/src/constants/ui.d.ts +0 -1
  80. package/lib/src/css/library.brand-page-brandCrowd.min.css +225 -134
  81. package/lib/src/css/library.brand-page-brandPage.min.css +227 -121
  82. package/lib/src/css/library.brand-page-designCom.min.css +225 -134
  83. package/lib/src/css/library.brand-page-preview.min.css +225 -118
  84. package/lib/src/index.d.ts +1 -1
  85. package/lib/src/index.mjs +1 -1
  86. package/lib/src/{lib-33w_DBny.js → lib-CSRUPpSo.js} +30887 -29395
  87. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +21 -0
  88. package/lib/src/metadata-builder/ai-metadata-executor.js +56 -3
  89. package/lib/src/metadata-builder/builders/add-page-builder.d.ts +2 -4
  90. package/lib/src/metadata-builder/builders/add-page-builder.js +5 -8
  91. package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
  92. package/lib/src/metadata-builder/builders/footer-builder.js +151 -0
  93. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
  94. package/lib/src/metadata-builder/builders/global-styles-builder.js +129 -0
  95. package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
  96. package/lib/src/metadata-builder/builders/header-builder.js +167 -0
  97. package/lib/src/metadata-builder/builders/rename-page-builder.d.ts +12 -0
  98. package/lib/src/metadata-builder/builders/rename-page-builder.js +49 -0
  99. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +2 -0
  100. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +44 -4
  101. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +2 -0
  102. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +70 -6
  103. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +36 -4
  104. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +102 -12
  105. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +8 -0
  106. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
  107. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +2 -0
  108. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +5 -1
  109. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +2 -0
  110. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +47 -3
  111. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +2 -1
  112. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +5 -2
  113. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +2 -0
  114. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +11 -1
  115. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +2 -0
  116. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +52 -13
  117. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +2 -0
  118. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +47 -17
  119. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
  120. package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
  121. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +2 -0
  122. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +20 -2
  123. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +2 -0
  124. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +20 -2
  125. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +2 -0
  126. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +36 -2
  127. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +2 -0
  128. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +70 -27
  129. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +2 -0
  130. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +7 -2
  131. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +2 -0
  132. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +91 -26
  133. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +2 -0
  134. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +69 -31
  135. package/lib/src/metadata-builder/builders/section-content-factory.d.ts +2 -2
  136. package/lib/src/metadata-builder/builders/section-content-factory.js +8 -2
  137. package/lib/src/metadata-builder/builders/section-field-maps.js +30 -2
  138. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +46 -7
  139. package/lib/src/metadata-builder/builders/section-field-utils.js +86 -62
  140. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.d.ts +2 -0
  141. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.js +20 -0
  142. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.d.ts +7 -0
  143. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.js +8 -0
  144. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.d.ts +2 -0
  145. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +27 -0
  146. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.d.ts +2 -0
  147. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.js +16 -0
  148. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.d.ts +2 -0
  149. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.js +13 -0
  150. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.d.ts +2 -0
  151. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.js +16 -0
  152. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.d.ts +2 -0
  153. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.js +7 -0
  154. package/lib/src/metadata-builder/builders/section-rules/footer.rules.d.ts +4 -0
  155. package/lib/src/metadata-builder/builders/section-rules/footer.rules.js +5 -0
  156. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +6 -0
  157. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +26 -0
  158. package/lib/src/metadata-builder/builders/section-rules/header.rules.d.ts +4 -0
  159. package/lib/src/metadata-builder/builders/section-rules/header.rules.js +41 -0
  160. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.d.ts +2 -0
  161. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.js +10 -0
  162. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.d.ts +2 -0
  163. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.js +31 -0
  164. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.d.ts +2 -0
  165. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.js +11 -0
  166. package/lib/src/metadata-builder/builders/section-rules/profile.rules.d.ts +2 -0
  167. package/lib/src/metadata-builder/builders/section-rules/profile.rules.js +14 -0
  168. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.d.ts +7 -0
  169. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.js +8 -0
  170. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.d.ts +2 -0
  171. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.js +27 -0
  172. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.d.ts +2 -0
  173. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +9 -0
  174. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.d.ts +7 -0
  175. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.js +26 -0
  176. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.d.ts +2 -0
  177. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.js +14 -0
  178. package/lib/src/metadata-builder/builders/shape-color-utils.d.ts +26 -0
  179. package/lib/src/metadata-builder/builders/shape-color-utils.js +52 -0
  180. package/lib/src/metadata-builder/builders/undo-builder.d.ts +48 -0
  181. package/lib/src/metadata-builder/builders/undo-builder.js +58 -0
  182. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +15 -4
  184. package/lib/src/metadata-builder/helpers/rte.helpers.js +24 -10
  185. package/lib/src/metadata-builder/metadata-executor.d.ts +2 -1
  186. package/lib/src/metadata-builder/metadata-executor.js +32 -5
  187. package/lib/src/metadata-builder/models.d.ts +26 -1
  188. package/lib/src/metadata-builder/models.js +14 -1
  189. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +144 -0
  190. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +17 -0
  191. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +113 -24
  192. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
  193. package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +22 -0
  194. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +84 -0
  195. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +47 -0
  196. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +60 -0
  197. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +41 -0
  198. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +274 -0
  199. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -1
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -16
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.stories.js +0 -1
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -1
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -3
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -4
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +6 -8
  206. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -28
  207. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -1
  208. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -28
  209. package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
  210. package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
  211. package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
  212. package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
  213. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -30
  214. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -28
  215. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -43
  216. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -30
  217. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +2 -3
  218. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +0 -12
  219. package/lib/src/shared/side-bar/store/side-bar-store.js +0 -7
  220. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -29
  221. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +2 -1
  222. package/lib/src/utils/build-asset-manifest.d.ts +26 -0
  223. package/lib/src/utils/build-asset-manifest.js +114 -0
  224. package/lib/src/utils/minify-brand-page-metadata.d.ts +49 -1
  225. package/lib/src/utils/minify-brand-page-metadata.js +216 -129
  226. package/package.json +1 -1
  227. package/src/brand-page/components/banner-section/BannerSection.vue +1 -1
  228. package/src/brand-page/components/contact-form/ContactForm.vue +29 -26
  229. package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
  230. package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -5
  231. package/src/brand-page/models/brand-page-context.model.ts +1 -25
  232. package/src/brand-page/models/index.ts +1 -0
  233. package/src/brand-page/utils/color.util.test.ts +48 -0
  234. package/src/brand-page/utils/color.util.ts +29 -4
  235. package/src/brand-page/utils/raygun.util.ts +11 -2
  236. package/src/brand-page/utils/svg-color.util.ts +1 -3
  237. package/src/brand-page/utils/view-model.util.ts +1 -4
  238. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
  239. package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
  240. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +57 -5
  241. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.de-DE.json +0 -20
  242. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.es-ES.json +0 -20
  243. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-CA.json +0 -20
  244. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-FR.json +0 -20
  245. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.json +0 -20
  246. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-BR.json +0 -20
  247. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-PT.json +0 -20
  248. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
  249. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.de-DE.json +3 -0
  250. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.es-ES.json +3 -0
  251. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-CA.json +3 -0
  252. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-FR.json +3 -0
  253. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.json +3 -0
  254. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-BR.json +3 -0
  255. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-PT.json +3 -0
  256. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +3 -28
  257. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -2
  258. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.test.ts +229 -0
  259. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +164 -0
  260. package/src/brand-page-maker/composables/ai-chat/types.ts +49 -0
  261. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +20 -0
  262. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +651 -94
  263. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +9 -9
  264. package/src/brand-page-maker/composables/useEventTracker.ts +31 -25
  265. package/src/brand-page-maker/constants/sidebar-constant.ts +7 -15
  266. package/src/brand-page-maker/convertors/image-aspect-ratio.convertor.ts +2 -2
  267. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +3 -3
  268. package/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.ts +54 -0
  269. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
  270. package/src/brand-page-maker/stores/index.ts +1 -1
  271. package/src/brand-page-maker/stores/user/user-store.ts +0 -1
  272. package/src/bundles/bundled-translations.de-DE.json +1 -20
  273. package/src/bundles/bundled-translations.es-ES.json +1 -20
  274. package/src/bundles/bundled-translations.fr-CA.json +1 -20
  275. package/src/bundles/bundled-translations.fr-FR.json +1 -20
  276. package/src/bundles/bundled-translations.json +1 -20
  277. package/src/bundles/bundled-translations.pt-BR.json +1 -20
  278. package/src/bundles/bundled-translations.pt-PT.json +1 -20
  279. package/src/clients/ai-assistant-client.ts +59 -46
  280. package/src/clients/design-template-client.ts +0 -66
  281. package/src/clients/websocket-gateway-client.ts +17 -1
  282. package/src/composables/useTranslate.ts +3 -0
  283. package/src/constants/ui.ts +0 -1
  284. package/src/lib.ts +1 -0
  285. package/src/metadata-builder/ai-metadata-executor.ts +94 -1
  286. package/src/metadata-builder/builders/add-page-builder.ts +9 -13
  287. package/src/metadata-builder/builders/footer-builder.test.ts +76 -0
  288. package/src/metadata-builder/builders/footer-builder.ts +226 -0
  289. package/src/metadata-builder/builders/global-styles-builder.ts +187 -0
  290. package/src/metadata-builder/builders/header-builder.test.ts +106 -0
  291. package/src/metadata-builder/builders/header-builder.ts +254 -0
  292. package/src/metadata-builder/builders/rename-page-builder.ts +79 -0
  293. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +73 -5
  294. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +112 -7
  295. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +149 -11
  296. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +87 -0
  297. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +6 -1
  298. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +74 -4
  299. package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +15 -1
  300. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +13 -1
  301. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +91 -31
  302. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +102 -48
  303. package/src/metadata-builder/builders/section-builders/index.ts +1 -0
  304. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +38 -2
  305. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +38 -2
  306. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +55 -3
  307. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +170 -77
  308. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +119 -0
  309. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +13 -2
  310. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +178 -57
  311. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +130 -30
  312. package/src/metadata-builder/builders/section-content-factory.ts +15 -2
  313. package/src/metadata-builder/builders/section-field-maps.ts +34 -1
  314. package/src/metadata-builder/builders/section-field-utils.ts +131 -72
  315. package/src/metadata-builder/builders/section-rules/about-section.rules.ts +38 -0
  316. package/src/metadata-builder/builders/section-rules/add-page.rules.ts +17 -0
  317. package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +49 -0
  318. package/src/metadata-builder/builders/section-rules/booking-section.rules.ts +34 -0
  319. package/src/metadata-builder/builders/section-rules/button-section.rules.ts +22 -0
  320. package/src/metadata-builder/builders/section-rules/contact-form.rules.ts +30 -0
  321. package/src/metadata-builder/builders/section-rules/divider-section.rules.ts +17 -0
  322. package/src/metadata-builder/builders/section-rules/footer.rules.ts +21 -0
  323. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +44 -0
  324. package/src/metadata-builder/builders/section-rules/header.rules.ts +75 -0
  325. package/src/metadata-builder/builders/section-rules/image-gallery.rules.ts +22 -0
  326. package/src/metadata-builder/builders/section-rules/images-section.rules.ts +55 -0
  327. package/src/metadata-builder/builders/section-rules/mailing-list.rules.ts +21 -0
  328. package/src/metadata-builder/builders/section-rules/profile.rules.ts +27 -0
  329. package/src/metadata-builder/builders/section-rules/rename-page.rules.ts +17 -0
  330. package/src/metadata-builder/builders/section-rules/shapes-section.rules.ts +51 -0
  331. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +27 -0
  332. package/src/metadata-builder/builders/section-rules/testimonial-section.rules.ts +48 -0
  333. package/src/metadata-builder/builders/section-rules/text-section.rules.ts +28 -0
  334. package/src/metadata-builder/builders/shape-color-utils.test.ts +115 -0
  335. package/src/metadata-builder/builders/shape-color-utils.ts +75 -0
  336. package/src/metadata-builder/builders/undo-builder.ts +105 -0
  337. package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -1
  338. package/src/metadata-builder/helpers/rte.helpers.ts +27 -13
  339. package/src/metadata-builder/metadata-executor.ts +42 -2
  340. package/src/metadata-builder/models.ts +39 -1
  341. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +152 -0
  342. package/src/metadata-builder/parsers/section-tool-arguments.ts +138 -24
  343. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +659 -0
  344. package/src/metadata-builder/sanitizers/rte-schema-check.ts +99 -0
  345. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +97 -0
  346. package/src/metadata-builder/sanitizers/section-args-validator.ts +445 -0
  347. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +10 -16
  348. package/src/shared/content-settings/components/content-settings/ContentSettings.stories.ts +0 -1
  349. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -10
  350. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -23
  351. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +0 -15
  352. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +0 -15
  353. package/src/shared/navigation-style-settings/store/index.ts +5 -0
  354. package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
  355. package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
  356. package/src/shared/side-bar/components/SideBar.vue +14 -1
  357. package/src/shared/side-bar/store/side-bar-store.ts +0 -20
  358. package/src/utils/build-asset-manifest.ts +153 -0
  359. package/src/utils/minify-brand-page-metadata.ts +362 -130
  360. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +0 -368
  361. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.d.ts +0 -18
  362. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.js +0 -144
  363. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +0 -155
  364. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.js +0 -25
  365. package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +0 -1
  366. package/lib/src/brand-page-maker/utils/mixpanel.util.js +0 -29
  367. package/lib/src/bundled-translations-CNK7l6_v.js +0 -173
  368. package/lib/src/bundled-translations.de-DE-BLE4_y0H.js +0 -173
  369. package/lib/src/bundled-translations.es-ES-thO9osbg.js +0 -173
  370. package/lib/src/bundled-translations.fr-CA-BZkhiNgU.js +0 -173
  371. package/lib/src/bundled-translations.fr-FR-bhDLPKgZ.js +0 -173
  372. package/lib/src/bundled-translations.pt-BR-CI9a5Bq1.js +0 -173
  373. package/lib/src/bundled-translations.pt-PT-DBoErBaq.js +0 -173
  374. package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +0 -154
  375. package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +0 -562
  376. package/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.ts +0 -196
  377. package/src/brand-page-maker/stores/ai-thread/ai-thread-store.ts +0 -31
  378. package/src/brand-page-maker/utils/mixpanel.util.ts +0 -42
  379. package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +0 -114
  380. package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +0 -761
@@ -1,761 +0,0 @@
1
- <template>
2
- <div data-component="generate-ai-modal">
3
- <Modal
4
- full-screen-breakpoint="sm"
5
- :visible="props.isVisible"
6
- :close-on-esc="true"
7
- :hide-scrollbar="false"
8
- :show-modal-background-image="false"
9
- @close-modal="onClose"
10
- >
11
- <template #header>
12
- <h2
13
- class="tw-font-bold tw-text-2xl sm:tw-text-3xl tw-mb-2 tw-text-black tw-bg-grayscale-200 tw-flex tw-items-center"
14
- >
15
- <Icon name="ai" size="lg" class="tw-mr-2 tw-text-primary-500" />
16
- {{ generateAiModalTr('generateTitle') }}
17
- </h2>
18
- </template>
19
- <template #default>
20
- <div
21
- class="tw-overflow-hidden tw-bg-white tw-rounded-lg tw-shadow-md tw-text-left tw-border-grayscale-500 tw-border tw-border-solid tw-flex tw-flex-col tw-h-full"
22
- >
23
- <div
24
- class="tw-p-3 tw-flex-1 tw-overflow-auto tw-flex tw-flex-col tw-justify-between"
25
- >
26
- <div
27
- class="tw-p-2 tw-rounded-md tw-mb-4 tw-block"
28
- :class="{
29
- 'c-modal-dcom': isDesignCom,
30
- 'c-modal-bc': !isDesignCom,
31
- }"
32
- >
33
- <div
34
- class="tw-flex tw-text-sm tw-items-start tw-text-grayscale-600"
35
- >
36
- <SparkleIcon
37
- v-if="isProcessing"
38
- color-class="tw-text-primary-500"
39
- animated
40
- class="tw-mr-2 tw-flex tw-flex-shrink-0 tw-mt-0.5"
41
- />
42
- <Icon
43
- v-else
44
- name="ai"
45
- size="sm"
46
- class="tw-mr-2 tw-text-primary-500 tw-flex tw-flex-shrink-0 tw-mt-0.5"
47
- />
48
- <p class="tw-flex-1 tw-max-h-64 tw-overflow-y-auto">
49
- {{ response }}
50
- <span v-if="data.isTyping" class="typing-cursor">|</span>
51
- </p>
52
- </div>
53
- <div class="tw-flex tw-justify-end tw-gap-2">
54
- <div
55
- v-if="isDoneTyping"
56
- class="tw-flex tw-gap-2 tw-items-center tw-mt-2"
57
- >
58
- <div class="tw-relative tw-group">
59
- <Icon
60
- v-if="!data.isCopied"
61
- name="duplicate"
62
- size="sm"
63
- class="tw-cursor-pointer hover:tw-text-info-700"
64
- @click="copyToClipboard"
65
- />
66
- <Icon v-else name="check" size="sm" class="text-success" />
67
- <span
68
- v-if="!data.isCopied"
69
- class="tw-absolute tw-bottom-full tw-left-1/2 tw--translate-x-1/2 tw-mb-2 tw-px-2 tw-py-1 tw-text-xs tw-text-white tw-bg-grayscale-800 tw-rounded tw-whitespace-nowrap tw-opacity-0 group-hover:tw-opacity-100 tw-transition-opacity tw-pointer-events-none"
70
- >
71
- {{ commonTr('copy') }}
72
- </span>
73
- </div>
74
- <Button
75
- classes="tw-w-full tw-h-full"
76
- :label="commonTr('regenerateText')"
77
- variant="primary"
78
- size="small"
79
- :attrs="{ 'data-test-tag': 'regenerate-btn' }"
80
- @click="onRegeneratePrompt"
81
- />
82
- <Button
83
- classes="tw-w-full tw-h-full"
84
- :label="generateAiModalTr('useText')"
85
- variant="primary"
86
- size="small"
87
- :attrs="{ 'data-test-tag': 'use-text-btn' }"
88
- @click="onUseText"
89
- />
90
- </div>
91
- <div v-if="data.isApiRequesting">
92
- <Button
93
- classes="tw-w-full tw-h-full"
94
- :label="generateAiModalTr('stopGeneration')"
95
- variant="primary"
96
- size="small"
97
- icon-left="stop"
98
- :attrs="{ 'data-test-tag': 'stop-btn' }"
99
- @click="onStopGeneration"
100
- />
101
- </div>
102
- </div>
103
- </div>
104
- <p class="tw-text-xs text-grayscale tw-flex tw-items-center">
105
- <Icon name="callout-info" size="sm" class="tw-mr-1 tw-flex" />
106
- {{ generateAiModalTr('generateDescription') }}
107
- </p>
108
- </div>
109
- <!-- Suggested prompts - Mobile (shown above textarea) -->
110
- <div
111
- class="suggested-prompts-container suggested-prompts-mobile tw-border-t tw-border-solid tw-border-grayscale-500"
112
- >
113
- <Button
114
- v-for="prompt in suggestedPrompts"
115
- :key="prompt.id"
116
- classes="tw-w-full sm:tw-w-auto tw-h-full tw-font-normal tw-max-h-9 tw-flex tw-justify-center tw-items-center"
117
- :class="{
118
- 'tw-uppercase': !isDesignCom,
119
- 'disabled-button': prompt.disabled,
120
- }"
121
- :label="prompt.label"
122
- variant="flat"
123
- size="small"
124
- :disabled="prompt.disabled"
125
- :attrs="{
126
- 'data-test-tag': prompt.testTag,
127
- }"
128
- @click="prompt.handler"
129
- />
130
- </div>
131
- <div
132
- class="tw-p-3 tw-flex tw-flex-col sm:tw-flex-row tw-gap-2 tw-border-t tw-border-solid tw-border-grayscale-500"
133
- >
134
- <div class="tw-flex tw-flex-col tw-flex-1 tw-gap-1">
135
- <div class="tw-flex tw-items-center tw-flex-1">
136
- <textarea
137
- ref="textareaRef"
138
- v-model="data.prompt"
139
- :placeholder="generateAiModalTr('generateInputPlaceholder')"
140
- :disabled="isProcessing"
141
- rows="1"
142
- class="prompt-textarea tw-font-sans tw-box-border tw-w-full tw-py-2 tw-text-sm tw-px-4 tw-rounded tw-border tw-border-solid tw-transition-colors tw-duration-300 tw-ease-out tw-shadow-inner tw-resize-none tw-overflow-y-auto sm:tw-min-h-10"
143
- :class="{
144
- 'tw-border-error-600 focus:tw-border-error-700':
145
- isPromptTooLong,
146
- 'tw-border-grayscale-500 focus:tw-border-grayscale-600':
147
- !isPromptTooLong,
148
- 'tw-bg-grayscale-300': isProcessing,
149
- }"
150
- @input="resizeTextarea"
151
- />
152
- </div>
153
- <p
154
- v-if="data.promptError"
155
- class="tw-text-xs tw-text-error-600 tw-mt-1"
156
- >
157
- {{ data.promptError }}
158
- </p>
159
- </div>
160
- <Button
161
- classes="tw-w-full sm:tw-w-auto tw-h-full tw-max-h-10"
162
- class="tw-flex tw-justify-center tw-items-center"
163
- :label="commonTr('sendButtonText')"
164
- variant="primary"
165
- size="small-medium"
166
- icon-left="send"
167
- icon-left-size="sm"
168
- :disabled="!data.prompt.trim() || isProcessing || isPromptTooLong"
169
- :attrs="{
170
- 'data-test-tag': 'send-btn',
171
- }"
172
- @click="onSendButtonClick"
173
- />
174
- </div>
175
- <!-- Suggested prompts - Desktop (shown below textarea) -->
176
- <div
177
- class="suggested-prompts-container suggested-prompts-desktop tw-border-t tw-border-solid tw-border-grayscale-500"
178
- >
179
- <Button
180
- v-for="prompt in suggestedPrompts"
181
- :key="prompt.id"
182
- classes="tw-w-full sm:tw-w-auto tw-h-full tw-font-normal tw-max-h-9 tw-flex tw-justify-center tw-items-center"
183
- :class="{
184
- 'tw-uppercase': !isDesignCom,
185
- 'disabled-button': prompt.disabled,
186
- }"
187
- :label="prompt.label"
188
- variant="flat"
189
- size="small"
190
- :disabled="prompt.disabled"
191
- :attrs="{
192
- 'data-test-tag': prompt.testTag,
193
- }"
194
- @click="prompt.handler"
195
- />
196
- </div>
197
- </div>
198
- </template>
199
- </Modal>
200
- </div>
201
- </template>
202
-
203
- <script setup lang="ts">
204
- import { Modal, Icon, Button, SparkleIcon } from '@designcrowd/fe-shared-lib';
205
- import { computed, reactive, onUnmounted, watch, ref, nextTick } from 'vue';
206
- import {
207
- generateAiModalTr,
208
- commonTr,
209
- contentSettingsTr,
210
- } from '@src/composables/useTranslate';
211
- import { getInstance as getDesignTemplateClient } from '../../../../clients/design-template-client';
212
- import {
213
- EVENTS,
214
- GENERATE_AI_SUGGESTED_PROMPT,
215
- GENERATE_TEXT_CONTINUATION_EVENTS,
216
- useEventTracker,
217
- } from '@brand-page-maker/composables/useEventTracker';
218
- import { useSnapshotStore } from '@brand-page-maker/stores';
219
- import { useBrandPageMakerStore } from '@brand-page-maker/stores';
220
-
221
- interface Props {
222
- id: string;
223
- isVisible: boolean;
224
- existingText?: string;
225
- isDesignCom?: boolean;
226
- ctaLocation: string;
227
- fieldName: string;
228
- }
229
-
230
- const props = withDefaults(defineProps<Props>(), {
231
- isVisible: true,
232
- existingText: '',
233
- snapshotBase64: null,
234
- });
235
-
236
- const data = reactive({
237
- prompt: '',
238
- response: null as string | null,
239
- lastPromptSent: '',
240
- isApiRequesting: false,
241
- isTyping: false,
242
- isStopped: false,
243
- typingIntervalId: null as number | null,
244
- isCopied: false,
245
- promptError: '',
246
- });
247
-
248
- const eventTracker = useEventTracker();
249
- const textareaRef = ref<HTMLTextAreaElement | null>(null);
250
- const MAX_PROMPT_LENGTH = 2000;
251
-
252
- const snapshotStore = useSnapshotStore();
253
- const snapshotBase64 = computed(() => snapshotStore.snapshotBase64);
254
-
255
- const brandPageMakerStore = useBrandPageMakerStore();
256
-
257
- const businessName = computed(() => brandPageMakerStore.businessName || '');
258
- const industry = computed(() => brandPageMakerStore.industry || '');
259
-
260
- // Auto-resize textarea
261
- const resizeTextarea = () => {
262
- if (textareaRef.value) {
263
- textareaRef.value.style.height = 'auto';
264
- textareaRef.value.style.height = `${textareaRef.value.scrollHeight}px`;
265
- }
266
- };
267
-
268
- const isProcessing = computed(() => data.isApiRequesting || data.isTyping);
269
-
270
- const response = computed(() => {
271
- if (isProcessing.value && data.response === null) {
272
- return '';
273
- }
274
- if (data.response !== null) {
275
- return data.response;
276
- }
277
- // Show existing text if available, otherwise show placeholder
278
- return props.existingText || generateAiModalTr('generatePlaceholder');
279
- });
280
-
281
- const isDoneTyping = computed(
282
- () => !isProcessing.value && data.response !== null,
283
- );
284
-
285
- const isPromptTooLong = computed(() => data.prompt.length > MAX_PROMPT_LENGTH);
286
-
287
- const formattedLocation = computed(() => {
288
- const parts = props.ctaLocation.split('_');
289
-
290
- // Special cases: testimonial and text items only need content type
291
- if (parts[0] === 'testimonial' || parts[0] === 'text') {
292
- return contentSettingsTr(`${parts[0]}DisplayName`);
293
- }
294
-
295
- // Standard case: content type + field name
296
- const contentType = contentSettingsTr(`${parts[0]}SectionDisplayName`);
297
- const fieldName = contentSettingsTr(`${parts.slice(1).join('_')}Title`);
298
- return `${contentType} ${fieldName}`;
299
- });
300
-
301
- const suggestedPrompts = computed(() => [
302
- {
303
- id: 'generate-text',
304
- label: generateAiModalTr('generateText', {
305
- location: formattedLocation.value,
306
- }),
307
- disabled: isProcessing.value,
308
- testTag: 'generate-text-btn',
309
- handler: onGenerateTextClick,
310
- },
311
- {
312
- id: 'improve-text',
313
- label: generateAiModalTr('improveText'),
314
- disabled: !props.existingText?.trim() || isProcessing.value,
315
- testTag: 'improve-text-btn',
316
- handler: onImproveTextClick,
317
- },
318
- {
319
- id: 'spell-check',
320
- label: generateAiModalTr('spellCheck'),
321
- disabled: !props.existingText?.trim() || isProcessing.value,
322
- testTag: 'spell-check-btn',
323
- handler: onSpellCheckClick,
324
- },
325
- ]);
326
-
327
- // Watch prompt length and set error
328
- watch(
329
- () => data.prompt,
330
- (newPrompt) => {
331
- if (newPrompt.length > MAX_PROMPT_LENGTH) {
332
- data.promptError = generateAiModalTr('promptTooLong', {
333
- maxLength: MAX_PROMPT_LENGTH,
334
- currentLength: newPrompt.length,
335
- });
336
- } else {
337
- data.promptError = '';
338
- }
339
-
340
- // Resize textarea on next tick to ensure DOM is updated
341
- nextTick(() => {
342
- resizeTextarea();
343
- });
344
- },
345
- );
346
-
347
- const emit = defineEmits(['on-close', 'on-use-text']);
348
-
349
- const clearTypingInterval = () => {
350
- if (data.typingIntervalId) {
351
- clearInterval(data.typingIntervalId);
352
- data.typingIntervalId = null;
353
- }
354
- };
355
-
356
- const stopGeneration = () => {
357
- data.isStopped = true;
358
- data.isApiRequesting = false;
359
- data.isTyping = false;
360
- clearTypingInterval();
361
- };
362
-
363
- const resetModalState = () => {
364
- data.response = null;
365
- data.prompt = '';
366
- data.isCopied = false;
367
- data.promptError = '';
368
- data.isApiRequesting = false;
369
- data.isTyping = false;
370
- };
371
-
372
- const onClose = () => {
373
- // Mark as stopped so API response is ignored
374
- data.isStopped = true;
375
- clearTypingInterval();
376
-
377
- // Reset UI state
378
- resetModalState();
379
-
380
- emit('on-close');
381
- };
382
-
383
- const typeText = (fullText: string) => {
384
- clearTypingInterval();
385
-
386
- data.response = '';
387
- data.isTyping = true;
388
- let index = 0;
389
- const charsPerTick = fullText.length > 150 ? 2 : 1;
390
-
391
- data.typingIntervalId = window.setInterval(() => {
392
- // Check if generation was stopped
393
- if (data.isStopped) {
394
- clearTypingInterval();
395
- data.isTyping = false;
396
- return;
397
- }
398
-
399
- if (index < fullText.length) {
400
- index = Math.min(index + charsPerTick, fullText.length);
401
- data.response = fullText.substring(0, index);
402
- } else {
403
- clearTypingInterval();
404
- data.isTyping = false;
405
- }
406
- }, 20);
407
- };
408
-
409
- const copyToClipboard = async () => {
410
- if (!data.response) return;
411
-
412
- eventTracker.sendWebsiteEvent({
413
- eventName: EVENTS.WEBSITE_MAKER_AI_COPY_RESPONSE,
414
- eventProps: {
415
- cta_location: props.ctaLocation,
416
- },
417
- });
418
-
419
- try {
420
- await navigator.clipboard.writeText(data.response);
421
- data.isCopied = true;
422
-
423
- // Reset the icon back to duplicate after 2 seconds
424
- setTimeout(() => {
425
- data.isCopied = false;
426
- }, 2000);
427
- } catch (error) {
428
- console.error('Failed to copy text:', error);
429
- }
430
- };
431
-
432
- const onUseText = () => {
433
- if (!data.response) return;
434
-
435
- eventTracker.sendGenerateTextContinuationEvent(
436
- props.ctaLocation,
437
- GENERATE_TEXT_CONTINUATION_EVENTS.USE_TEXT,
438
- );
439
-
440
- emit('on-use-text', data.response);
441
- onClose();
442
- };
443
-
444
- const onStopGeneration = () => {
445
- eventTracker.sendWebsiteEvent({
446
- eventName: EVENTS.WEBSITE_MAKER_AI_STOP_GENERATION,
447
- eventProps: {
448
- cta_location: props.ctaLocation,
449
- },
450
- });
451
- stopGeneration();
452
- data.response = generateAiModalTr('generationStopped');
453
- };
454
- const onRegeneratePrompt = () => {
455
- if (data.lastPromptSent) {
456
- eventTracker.sendWebsiteEvent({
457
- eventName: EVENTS.WEBSITE_MAKER_AI_REGENERATE_TEXT,
458
- eventProps: {
459
- cta_location: props.ctaLocation,
460
- },
461
- });
462
- onSendPrompt(data.lastPromptSent);
463
- }
464
- };
465
-
466
- const onSendButtonClick = () => {
467
- eventTracker.sendWebsiteEvent({
468
- eventName: EVENTS.WEBSITE_MAKER_AI_SEND_PROMPT,
469
- eventProps: {
470
- cta_location: props.ctaLocation,
471
- },
472
- });
473
- onSendPrompt();
474
- };
475
-
476
- // Helper function to build prompt key based on available context
477
- const buildPromptKey = (baseKey: string): string => {
478
- if (businessName.value && industry.value) return baseKey;
479
- if (industry.value) return `${baseKey}WithIndustry`;
480
- if (businessName.value) return `${baseKey}WithBusinessName`;
481
- return `${baseKey}Simple`;
482
- };
483
-
484
- // Helper function to get prompt params based on available context
485
- const getPromptParams = (includeFieldName = false) => {
486
- const params: Record<string, string> = {};
487
-
488
- if (includeFieldName) {
489
- params.fieldName = formattedLocation.value;
490
- }
491
-
492
- if (businessName.value) {
493
- params.businessName = businessName.value;
494
- }
495
-
496
- if (industry.value) {
497
- params.industry = industry.value;
498
- }
499
-
500
- return params;
501
- };
502
-
503
- // Helper function to set prompt and focus textarea
504
- const setPromptAndFocus = (prompt: string) => {
505
- data.prompt = prompt;
506
-
507
- nextTick(() => {
508
- resizeTextarea();
509
- textareaRef.value?.focus();
510
- });
511
- };
512
-
513
- const onGenerateTextClick = () => {
514
- const promptKey = buildPromptKey('generateTextPrompt');
515
- const prompt = generateAiModalTr(promptKey, getPromptParams(true));
516
-
517
- setPromptAndFocus(prompt);
518
-
519
- eventTracker.sendWebsiteEvent({
520
- eventName: EVENTS.WEBSITE_MAKER_AI_CLICK_SUGGESTED_PROMPT,
521
- eventProps: {
522
- cta_location: props.ctaLocation,
523
- prompt: GENERATE_AI_SUGGESTED_PROMPT.GENERATE_TEXT,
524
- },
525
- });
526
- };
527
-
528
- const onImproveTextClick = () => {
529
- const promptKey = buildPromptKey('improveTextPrompt');
530
- const prompt = generateAiModalTr(promptKey, getPromptParams(false));
531
-
532
- setPromptAndFocus(prompt);
533
-
534
- eventTracker.sendWebsiteEvent({
535
- eventName: EVENTS.WEBSITE_MAKER_AI_CLICK_SUGGESTED_PROMPT,
536
- eventProps: {
537
- cta_location: props.ctaLocation,
538
- prompt: GENERATE_AI_SUGGESTED_PROMPT.IMPROVE_TEXT,
539
- },
540
- });
541
- };
542
-
543
- const onSpellCheckClick = () => {
544
- const prompt = generateAiModalTr('spellCheckPrompt');
545
-
546
- setPromptAndFocus(prompt);
547
-
548
- eventTracker.sendWebsiteEvent({
549
- eventName: EVENTS.WEBSITE_MAKER_AI_CLICK_SUGGESTED_PROMPT,
550
- eventProps: {
551
- cta_location: props.ctaLocation,
552
- prompt: GENERATE_AI_SUGGESTED_PROMPT.SPELL_CHECK,
553
- },
554
- });
555
- };
556
-
557
- const onSendPrompt = async (customPrompt?: string) => {
558
- const promptToSend = customPrompt || data.prompt.trim();
559
-
560
- if (
561
- !promptToSend ||
562
- (!customPrompt && promptToSend.length > MAX_PROMPT_LENGTH)
563
- ) {
564
- return;
565
- }
566
-
567
- data.lastPromptSent = promptToSend;
568
- data.isStopped = false;
569
- data.isApiRequesting = true;
570
- data.isTyping = false;
571
- data.response = null;
572
- data.prompt = '';
573
- clearTypingInterval();
574
-
575
- try {
576
- const maxWaitTime = 5000;
577
- const pollInterval = 50;
578
- let elapsedTime = 0;
579
-
580
- // Wait for snapshot to be captured (triggered by button component)
581
- while (!snapshotBase64.value && elapsedTime < maxWaitTime) {
582
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
583
- elapsedTime += pollInterval;
584
- }
585
-
586
- const client = getDesignTemplateClient();
587
- const result = await client.generateText(
588
- promptToSend,
589
- props.existingText ?? '',
590
- snapshotBase64.value || undefined,
591
- businessName.value,
592
- industry.value,
593
- props.ctaLocation,
594
- props.id,
595
- props.fieldName,
596
- );
597
-
598
- // Check if generation was stopped before setting response
599
- if (data.isStopped) {
600
- data.isApiRequesting = false;
601
- return;
602
- }
603
-
604
- data.isApiRequesting = false;
605
-
606
- if (result) {
607
- typeText(result);
608
- } else {
609
- data.response = 'Failed to generate text. Please try again.';
610
- }
611
- } catch (error: any) {
612
- // Check if generation was stopped before setting error
613
- if (data.isStopped) {
614
- data.isApiRequesting = false;
615
- return;
616
- }
617
-
618
- data.isApiRequesting = false;
619
- data.response =
620
- error?.response?.data?.error || 'An error occurred. Please try again.';
621
- }
622
- };
623
-
624
- // Auto-generate text when modal opens if there's existing text
625
- watch(
626
- () => props.isVisible,
627
- (newValue, oldValue) => {
628
- if (newValue && !oldValue) {
629
- // Only reset when transitioning from closed to open
630
- resetModalState();
631
- data.isStopped = false;
632
- data.lastPromptSent = '';
633
- } else if (!newValue && oldValue) {
634
- // Modal is closing - stop everything immediately
635
- data.isStopped = true;
636
- clearTypingInterval();
637
- data.isApiRequesting = false;
638
- data.isTyping = false;
639
- }
640
- },
641
- { flush: 'sync' },
642
- );
643
-
644
- onUnmounted(clearTypingInterval);
645
- </script>
646
- <style scoped>
647
- .c-modal-dcom {
648
- background-color: #eceefe;
649
- border: 1px solid #3247c5;
650
- }
651
-
652
- .c-modal-bc {
653
- background-color: #cceaf7;
654
- border: 1px solid #0097d7;
655
- }
656
-
657
- .typing-cursor {
658
- display: inline-block;
659
- animation: blink 1s step-end infinite;
660
- color: #3247c5;
661
- font-weight: bold;
662
- margin-left: 2px;
663
- }
664
-
665
- .prompt-textarea {
666
- line-height: 1.5;
667
- min-height: 4.5rem; /* Minimum 3 rows on mobile (1.5em * 3) */
668
- max-height: calc(7.5em + 1rem); /* Maximum 5 rows */
669
- color: rgb(96 96 96);
670
- scrollbar-gutter: stable;
671
- overflow-y: auto;
672
- }
673
-
674
- /* Desktop: smaller minimum height */
675
- @media (min-width: 640px) {
676
- .prompt-textarea {
677
- min-height: 2.5rem; /* Single line on desktop */
678
- }
679
- }
680
-
681
- .prompt-textarea::placeholder {
682
- color: rgb(96 96 96 / 50%);
683
- }
684
-
685
- /* Ensure border is visible when scrollbar appears */
686
- .prompt-textarea::-webkit-scrollbar {
687
- width: 8px;
688
- }
689
-
690
- .prompt-textarea::-webkit-scrollbar-track {
691
- background: transparent;
692
- margin: 2px;
693
- }
694
-
695
- .prompt-textarea::-webkit-scrollbar-thumb {
696
- background: rgb(96 96 96 / 30%);
697
- border-radius: 4px;
698
- }
699
-
700
- .prompt-textarea::-webkit-scrollbar-thumb:hover {
701
- background: rgb(96 96 96 / 50%);
702
- }
703
-
704
- .text-grayscale {
705
- color: rgb(96 96 96 / 50%);
706
- }
707
-
708
- .text-success {
709
- --tw-text-opacity: 1;
710
- color: rgb(29 134 13 / var(--tw-text-opacity));
711
- }
712
-
713
- .disabled-button :deep(button) {
714
- background-color: rgb(229 231 235) !important;
715
- cursor: not-allowed !important;
716
- opacity: 0.6 !important;
717
- }
718
-
719
- .suggested-prompts-container {
720
- @apply tw-p-3 tw-flex tw-flex-wrap tw-gap-2 tw-overflow-auto;
721
- }
722
-
723
- .suggested-prompts-container :deep(button) {
724
- white-space: nowrap;
725
- font-weight: normal;
726
- max-height: 2.25rem;
727
- flex: 0 1 auto;
728
- }
729
-
730
- /* Mobile: show above textarea */
731
- .suggested-prompts-mobile {
732
- @apply tw-flex;
733
- flex-flow: row;
734
- }
735
-
736
- .suggested-prompts-desktop {
737
- @apply tw-hidden;
738
- }
739
-
740
- /* Desktop: show below textarea */
741
- @media (min-width: 640px) {
742
- .suggested-prompts-mobile {
743
- @apply tw-hidden;
744
- }
745
-
746
- .suggested-prompts-desktop {
747
- @apply tw-flex;
748
- }
749
- }
750
-
751
- @keyframes blink {
752
- 0%,
753
- 50% {
754
- opacity: 1;
755
- }
756
- 51%,
757
- 100% {
758
- opacity: 0;
759
- }
760
- }
761
- </style>