@brunoalz/smartgesti-site-editor 1.2.0 → 1.3.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 (74) hide show
  1. package/dist/editor/BlockSelector.js +5 -2
  2. package/dist/editor/BlockSelector.js.map +1 -1
  3. package/dist/editor/LandingPageEditor.d.ts.map +1 -1
  4. package/dist/editor/LandingPageEditor.js +163 -151
  5. package/dist/editor/LandingPageEditor.js.map +1 -1
  6. package/dist/editor/PropertyEditor/BlockPropertyEditor.d.ts.map +1 -1
  7. package/dist/editor/PropertyEditor/BlockPropertyEditor.js +86 -48
  8. package/dist/editor/PropertyEditor/BlockPropertyEditor.js.map +1 -1
  9. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts +6 -0
  10. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts.map +1 -0
  11. package/dist/engine/export/exporters/sections/AdminSectionExporters.js +157 -0
  12. package/dist/engine/export/exporters/sections/AdminSectionExporters.js.map +1 -0
  13. package/dist/engine/export/exporters/sections/index.d.ts.map +1 -1
  14. package/dist/engine/export/exporters/sections/index.js +37 -33
  15. package/dist/engine/export/exporters/sections/index.js.map +1 -1
  16. package/dist/engine/index.js +98 -95
  17. package/dist/engine/index.js.map +1 -1
  18. package/dist/engine/preview/Preview.d.ts.map +1 -1
  19. package/dist/engine/preview/Preview.js +165 -160
  20. package/dist/engine/preview/Preview.js.map +1 -1
  21. package/dist/engine/registry/blocks/sections/aboutSection.d.ts +3 -0
  22. package/dist/engine/registry/blocks/sections/aboutSection.d.ts.map +1 -0
  23. package/dist/engine/registry/blocks/sections/aboutSection.js +117 -0
  24. package/dist/engine/registry/blocks/sections/aboutSection.js.map +1 -0
  25. package/dist/engine/registry/blocks/sections/contactSection.d.ts +3 -0
  26. package/dist/engine/registry/blocks/sections/contactSection.d.ts.map +1 -0
  27. package/dist/engine/registry/blocks/sections/contactSection.js +118 -0
  28. package/dist/engine/registry/blocks/sections/contactSection.js.map +1 -0
  29. package/dist/engine/registry/blocks/sections/index.d.ts +3 -0
  30. package/dist/engine/registry/blocks/sections/index.d.ts.map +1 -1
  31. package/dist/engine/registry/blocks/sections/productShowcase.d.ts +3 -0
  32. package/dist/engine/registry/blocks/sections/productShowcase.d.ts.map +1 -0
  33. package/dist/engine/registry/blocks/sections/productShowcase.js +108 -0
  34. package/dist/engine/registry/blocks/sections/productShowcase.js.map +1 -0
  35. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts +3 -0
  36. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts.map +1 -0
  37. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js +246 -0
  38. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js.map +1 -0
  39. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts +3 -0
  40. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts.map +1 -0
  41. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js +287 -0
  42. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js.map +1 -0
  43. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts +3 -0
  44. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts.map +1 -0
  45. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js +287 -0
  46. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js.map +1 -0
  47. package/dist/engine/render/renderers/sections/index.js +26 -20
  48. package/dist/engine/render/renderers/sections/index.js.map +1 -1
  49. package/dist/engine/schema/siteDocument.d.ts +96 -2
  50. package/dist/engine/schema/siteDocument.d.ts.map +1 -1
  51. package/dist/engine/schema/siteDocument.js.map +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +109 -106
  55. package/dist/index.js.map +1 -1
  56. package/dist/shared/schema.d.ts +1 -1
  57. package/dist/shared/schema.d.ts.map +1 -1
  58. package/dist/shared/schema.js +7 -4
  59. package/dist/shared/schema.js.map +1 -1
  60. package/dist/shared/templates/index.d.ts +2 -0
  61. package/dist/shared/templates/index.d.ts.map +1 -1
  62. package/dist/shared/templates/index.js +42 -23
  63. package/dist/shared/templates/index.js.map +1 -1
  64. package/dist/shared/templates/smartgesti-admin.d.ts +3 -0
  65. package/dist/shared/templates/smartgesti-admin.d.ts.map +1 -0
  66. package/dist/shared/templates/smartgesti-admin.js +426 -0
  67. package/dist/shared/templates/smartgesti-admin.js.map +1 -0
  68. package/dist/utils/blockIcons.d.ts.map +1 -1
  69. package/dist/utils/blockIcons.js +3 -0
  70. package/dist/utils/blockIcons.js.map +1 -1
  71. package/dist/viewer/LandingPageViewer.d.ts.map +1 -1
  72. package/dist/viewer/LandingPageViewer.js +66 -65
  73. package/dist/viewer/LandingPageViewer.js.map +1 -1
  74. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  import { jsx as a } from "react/jsx-runtime";
2
- import { useState as H, useRef as B, useCallback as F, useEffect as L } from "react";
2
+ import { useState as A, useRef as B, useCallback as F, useEffect as V } from "react";
3
3
  import { matchDynamicPage as W } from "../engine/plugins/dynamicPageResolver.js";
4
4
  import { hydratePageWithContent as G } from "../engine/plugins/contentHydration.js";
5
5
  import { logger as z } from "../utils/logger.js";
6
- import { defaultThemeTokens as A } from "../engine/schema/themeTokens.js";
6
+ import { defaultThemeTokens as P } from "../engine/schema/themeTokens.js";
7
7
  import { exportPageToHtml as _ } from "../engine/export/exportHtml.js";
8
8
  import { createEmptySiteDocument as q } from "../engine/schema/siteDocument.js";
9
9
  function J(o) {
@@ -23,15 +23,15 @@ function re({
23
23
  apiBaseUrl: r,
24
24
  projectId: h,
25
25
  pageSlug: n,
26
- schoolSlug: g,
27
- schoolData: T,
26
+ schoolSlug: b,
27
+ schoolData: D,
28
28
  // reservado para header/navbar dinâmico (logo, nome da escola)
29
- contentProviders: c,
30
- onNavigate: P
29
+ contentProviders: C,
30
+ onNavigate: c
31
31
  }) {
32
- const [s, C] = H(null), [w, m] = H(null), [E, f] = H(!0), [V, I] = H(null), [M, y] = H(null), x = B(P);
33
- x.current = P;
34
- const D = F((e) => {
32
+ const [s, E] = A(null), [j, w] = A(null), [p, H] = A(!0), [f, I] = A(null), [M, y] = A(null), k = B(c);
33
+ k.current = c;
34
+ const L = F((e) => {
35
35
  const t = `<script>
36
36
  (function() {
37
37
  document.addEventListener('click', function(e) {
@@ -54,14 +54,14 @@ function re({
54
54
  <\/script>`;
55
55
  return e.includes("</body>") ? e.replace("</body>", `${t}</body>`) : e + t;
56
56
  }, []);
57
- if (L(() => {
57
+ if (V(() => {
58
58
  const e = (t) => {
59
- t.data?.type === "viewer-navigate" && t.data?.href && x.current && x.current(t.data.href);
59
+ t.data?.type === "viewer-navigate" && t.data?.href && k.current && k.current(t.data.href);
60
60
  };
61
61
  return window.addEventListener("message", e), () => window.removeEventListener("message", e);
62
- }, []), L(() => {
62
+ }, []), V(() => {
63
63
  let e = !1;
64
- return f(!0), I(null), (async () => {
64
+ return H(!0), I(null), (async () => {
65
65
  try {
66
66
  const t = await fetch(
67
67
  `${r}/sites/${o}?projectId=${h}`
@@ -71,49 +71,49 @@ function re({
71
71
  const i = await t.json();
72
72
  if (e) return;
73
73
  if (i.template) {
74
- const l = i.template.schemaVersion, j = i.template.pages && Array.isArray(i.template.pages);
75
- if (l === 2 || l === "2" || j) {
74
+ const l = i.template.schemaVersion, x = i.template.pages && Array.isArray(i.template.pages);
75
+ if (l === 2 || l === "2" || x) {
76
76
  const u = i.template;
77
- Array.isArray(u.pages) || (u.pages = []), u.schemaVersion !== 2 && u.schemaVersion !== "2" && (u.schemaVersion = 2), C(u);
77
+ Array.isArray(u.pages) || (u.pages = []), u.schemaVersion !== 2 && u.schemaVersion !== "2" && (u.schemaVersion = 2), E(u);
78
78
  } else
79
79
  throw new Error(
80
80
  "Formato de template legado não suportado. Por favor, recrie o site."
81
81
  );
82
82
  } else
83
- C(null);
84
- if (i.publishedHtml && J(i.publishedHtml) ? m(i.publishedHtml) : m(null), !i.template && !i.publishedHtml)
83
+ E(null);
84
+ if (i.publishedHtml && J(i.publishedHtml) ? w(i.publishedHtml) : w(null), !i.template && !i.publishedHtml)
85
85
  throw new Error("Template não encontrado");
86
86
  } catch (t) {
87
87
  e || I(
88
88
  t instanceof Error ? t.message : "Erro ao carregar landing page"
89
89
  );
90
90
  } finally {
91
- e || f(!1);
91
+ e || H(!1);
92
92
  }
93
93
  })(), () => {
94
94
  e = !0;
95
95
  };
96
- }, [o, r, h]), L(() => {
96
+ }, [o, r, h]), V(() => {
97
97
  if (!s) {
98
98
  y(null);
99
99
  return;
100
100
  }
101
101
  let e = !1;
102
- const t = Array.isArray(s.pages) ? s.pages : [], i = K(c);
102
+ const t = Array.isArray(s.pages) ? s.pages : [], i = K(C);
103
103
  if (i.size === 0) {
104
104
  y(null);
105
105
  return;
106
106
  }
107
- let l, j = {};
107
+ let l, x = {};
108
108
  if (n) {
109
109
  const d = t.find(
110
- (p) => p.slug === n || p.id === n
110
+ (m) => m.slug === n || m.id === n
111
111
  );
112
112
  if (d)
113
113
  l = d;
114
114
  else {
115
- const p = W(t, n);
116
- p && (l = p.page, j = p.params);
115
+ const m = W(t, n);
116
+ m && (l = m.page, x = m.params);
117
117
  }
118
118
  } else
119
119
  l = t.find((d) => d.id === "home") ?? t[0];
@@ -121,32 +121,33 @@ function re({
121
121
  y(null);
122
122
  return;
123
123
  }
124
- const k = !!l.dataSource, u = l.structure?.some(
124
+ const T = !!l.dataSource, u = l.structure?.some(
125
125
  (d) => d.type === "blogPostGrid"
126
126
  );
127
- if (!k && !u) {
127
+ if (!T && !u) {
128
128
  y(null);
129
129
  return;
130
130
  }
131
131
  let R = l;
132
- return !k && u && (R = {
132
+ return !T && u && (R = {
133
133
  ...l,
134
134
  dataSource: { mode: "list", provider: "blog-posts" }
135
- }), G(R, i, j).then((d) => {
135
+ }), G(R, i, x).then((d) => {
136
136
  if (e) return;
137
- const p = N(
137
+ const m = N(
138
138
  d,
139
139
  s,
140
- g,
141
- t
140
+ b,
141
+ t,
142
+ !1
142
143
  );
143
- y(p ?? null);
144
+ y(m ?? null);
144
145
  }).catch((d) => {
145
- e || (z.error("Error hydrating page:", d), y(null));
146
+ e || (z.error("Error in content hydration:", d), y(null));
146
147
  }), () => {
147
148
  e = !0;
148
149
  };
149
- }, [s, n, c, g]), E)
150
+ }, [s, n, C, b]), p)
150
151
  return /* @__PURE__ */ a(
151
152
  "div",
152
153
  {
@@ -159,7 +160,7 @@ function re({
159
160
  children: /* @__PURE__ */ a("div", { children: "Carregando..." })
160
161
  }
161
162
  );
162
- if (V)
163
+ if (f)
163
164
  return /* @__PURE__ */ a(
164
165
  "div",
165
166
  {
@@ -169,14 +170,14 @@ function re({
169
170
  justifyContent: "center",
170
171
  minHeight: "100vh"
171
172
  },
172
- children: /* @__PURE__ */ a("div", { children: V || "Landing page não encontrada" })
173
+ children: /* @__PURE__ */ a("div", { children: f || "Landing page não encontrada" })
173
174
  }
174
175
  );
175
- if (w && (!n || n === "home") && !s)
176
+ if (j && (!n || n === "home") && !s)
176
177
  return /* @__PURE__ */ a(
177
178
  "iframe",
178
179
  {
179
- srcDoc: D(w),
180
+ srcDoc: L(j),
180
181
  title: "Site publicado",
181
182
  style: {
182
183
  width: "100%",
@@ -188,8 +189,8 @@ function re({
188
189
  );
189
190
  if (!s)
190
191
  return null;
191
- const v = Array.isArray(s.pages) ? s.pages : [];
192
- if (v.length === 0)
192
+ const g = Array.isArray(s.pages) ? s.pages : [];
193
+ if (g.length === 0)
193
194
  return /* @__PURE__ */ a(
194
195
  "div",
195
196
  {
@@ -208,7 +209,7 @@ function re({
208
209
  return /* @__PURE__ */ a(
209
210
  "iframe",
210
211
  {
211
- srcDoc: D(M),
212
+ srcDoc: L(M),
212
213
  title: "Site",
213
214
  style: {
214
215
  width: "100%",
@@ -218,12 +219,12 @@ function re({
218
219
  }
219
220
  }
220
221
  );
221
- let b = (n ? v.find((e) => e.slug === n || e.id === n) : null) ?? null;
222
- if (!b && n) {
223
- const e = W(v, n);
224
- e && (b = e.page);
222
+ let v = (n ? g.find((e) => e.slug === n || e.id === n) : null) ?? null;
223
+ if (!v && n) {
224
+ const e = W(g, n);
225
+ e && (v = e.page);
225
226
  }
226
- if (b || (b = v.find((e) => e.id === "home") ?? v[0]), !b)
227
+ if (v || (v = g.find((e) => e.id === "home") ?? g[0]), !v)
227
228
  return /* @__PURE__ */ a(
228
229
  "div",
229
230
  {
@@ -236,11 +237,11 @@ function re({
236
237
  children: /* @__PURE__ */ a("div", { children: "Página não encontrada" })
237
238
  }
238
239
  );
239
- const $ = N(b, s, g, v);
240
+ const $ = N(v, s, b, g);
240
241
  return $ ? /* @__PURE__ */ a(
241
242
  "iframe",
242
243
  {
243
- srcDoc: D($),
244
+ srcDoc: L($),
244
245
  title: "Site",
245
246
  style: {
246
247
  width: "100%",
@@ -264,30 +265,30 @@ function re({
264
265
  }
265
266
  );
266
267
  }
267
- function N(o, r, h, n) {
268
- const g = {
268
+ function N(o, r, h, n, b = !0) {
269
+ const D = {
269
270
  ...o,
270
271
  structure: Array.isArray(o.structure) ? o.structure : []
271
- }, T = q(""), c = r.theme && typeof r.theme == "object" ? r.theme : null, P = c ? {
272
- ...A,
272
+ }, C = q(""), c = r.theme && typeof r.theme == "object" ? r.theme : null, s = c ? {
273
+ ...P,
273
274
  ...c,
274
- colors: c.colors && typeof c.colors == "object" ? { ...A.colors, ...c.colors } : A.colors,
275
- typography: c.typography && typeof c.typography == "object" ? { ...A.typography, ...c.typography } : A.typography
276
- } : T.theme, s = {
275
+ colors: c.colors && typeof c.colors == "object" ? { ...P.colors, ...c.colors } : P.colors,
276
+ typography: c.typography && typeof c.typography == "object" ? { ...P.typography, ...c.typography } : P.typography
277
+ } : C.theme, E = {
277
278
  ...r,
278
279
  schemaVersion: 2,
279
- theme: P
280
- }, C = h ? `/site/escola/${h}` : "/site", w = n ?? r.pages, m = w.find((f) => f.id === "home") ?? w[0], E = m && m.id !== g.id ? {
281
- ...m,
282
- structure: Array.isArray(m.structure) ? m.structure : []
280
+ theme: s
281
+ }, j = h ? `/site/escola/${h}` : "/site", w = n ?? r.pages, p = w.find((f) => f.id === "home") ?? w[0], H = p && p.id !== D.id ? {
282
+ ...p,
283
+ structure: Array.isArray(p.structure) ? p.structure : []
283
284
  } : void 0;
284
285
  try {
285
286
  const f = _(
286
- g,
287
- s,
288
- !0,
289
- C,
290
- E ? { layoutFromPage: E } : void 0
287
+ D,
288
+ E,
289
+ b,
290
+ j,
291
+ H ? { layoutFromPage: H } : void 0
291
292
  );
292
293
  return !f || !f.trim() ? null : f;
293
294
  } catch (f) {
@@ -1 +1 @@
1
- {"version":3,"file":"LandingPageViewer.js","sources":["../../src/viewer/LandingPageViewer.tsx"],"sourcesContent":["/**\n * Landing Page Viewer\n * Visualização pública da landing page.\n * Usa o mesmo mecanismo do Preview (editor): exportPageToHtml + iframe srcdoc.\n *\n * Supports dynamic pages via ContentProvider (Sprint 3):\n * - Optional `contentProviders` prop allows consumer to supply data providers\n * - Dynamic page resolution (e.g., \"blog/:slug\")\n * - Automatic content hydration before rendering\n */\n\nimport { useState, useEffect, useRef, useCallback } from \"react\";\nimport {\n SiteDocument,\n SitePage,\n exportPageToHtml,\n createEmptySiteDocument,\n defaultThemeTokens,\n} from \"../engine\";\nimport type { ContentProvider } from \"../engine/plugins/types\";\nimport { matchDynamicPage } from \"../engine/plugins/dynamicPageResolver\";\nimport {\n hydratePageWithContent,\n type ContentProviderMap,\n} from \"../engine/plugins/contentHydration\";\nimport { logger } from \"../utils/logger\";\n\n/** Verifica se o HTML tem conteúdo real no body (evita usar publishedHtml vazio) */\nfunction hasBodyContent(html: string): boolean {\n if (!html || typeof html !== \"string\") return false;\n const match = html.match(/<body[^>]*>([\\s\\S]*?)<\\/body>/i);\n const bodyInner = match ? match[1].trim() : \"\";\n return bodyInner.length > 50;\n}\n\nexport interface SchoolData {\n id: string;\n name: string;\n slug: string;\n logo_url?: string;\n}\n\ninterface LandingPageViewerProps {\n siteId: string;\n apiBaseUrl: string;\n projectId: string;\n /** Slug da página (ex.: avisos). Se não informado, usa home. */\n pageSlug?: string;\n /** Slug da escola no contexto /site/escola/:schoolSlug */\n schoolSlug?: string;\n /** Dados da escola para header/navbar dinâmico (quando em contexto escola) */\n schoolData?: SchoolData;\n /**\n * Content providers for dynamic pages (e.g., blog posts, products).\n * Supplied by the consumer project to connect plugin data to the viewer.\n */\n contentProviders?: ContentProvider[];\n /**\n * Callback for internal navigation (link clicks inside iframe).\n * Receives the href from clicked links. Consumer should use router navigation.\n */\n onNavigate?: (href: string) => void;\n}\n\n/**\n * Builds a ContentProviderMap from an array of providers.\n */\nfunction buildProviderMap(providers?: ContentProvider[]): ContentProviderMap {\n const map: ContentProviderMap = new Map();\n if (providers) {\n for (const p of providers) {\n map.set(p.type, p);\n }\n }\n return map;\n}\n\nexport function LandingPageViewer({\n siteId,\n apiBaseUrl,\n projectId,\n pageSlug,\n schoolSlug,\n schoolData: _schoolData, // reservado para header/navbar dinâmico (logo, nome da escola)\n contentProviders,\n onNavigate,\n}: LandingPageViewerProps) {\n const [document, setDocument] = useState<SiteDocument | null>(null);\n const [publishedHtml, setPublishedHtml] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [hydratedHtml, setHydratedHtml] = useState<string | null>(null);\n\n const onNavigateRef = useRef(onNavigate);\n onNavigateRef.current = onNavigate;\n\n // Inject click interceptor into iframe HTML so link clicks propagate to parent\n const injectClickInterceptor = useCallback((html: string): string => {\n const script = `<script>\n(function() {\n document.addEventListener('click', function(e) {\n var target = e.target;\n var anchor = target;\n while (anchor && anchor.tagName !== 'A') {\n anchor = anchor.parentElement;\n }\n if (anchor && anchor.tagName === 'A') {\n var href = anchor.getAttribute('href') || '';\n if (href && href !== '#' && !href.startsWith('javascript:')) {\n e.preventDefault();\n e.stopPropagation();\n window.parent.postMessage({ type: 'viewer-navigate', href: href }, '*');\n return;\n }\n }\n }, true);\n})();\n</script>`;\n if (html.includes(\"</body>\")) {\n return html.replace(\"</body>\", `${script}</body>`);\n }\n return html + script;\n }, []);\n\n // Listen for navigation messages from iframe\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === \"viewer-navigate\" && event.data?.href) {\n if (onNavigateRef.current) {\n onNavigateRef.current(event.data.href);\n }\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, []);\n\n // Load site document from API. Uses stale flag to prevent\n // React Strict Mode double-mount from causing duplicate state updates.\n useEffect(() => {\n let stale = false;\n\n setIsLoading(true);\n setError(null);\n\n (async () => {\n try {\n const response = await fetch(\n `${apiBaseUrl}/sites/${siteId}?projectId=${projectId}`,\n );\n if (!response.ok) {\n throw new Error(\"Landing page não encontrada\");\n }\n\n const data = await response.json();\n if (stale) return;\n\n if (data.template) {\n const schemaVersion = data.template.schemaVersion;\n const hasPages =\n data.template.pages && Array.isArray(data.template.pages);\n const isV2 =\n schemaVersion === 2 || schemaVersion === \"2\" || hasPages;\n\n if (isV2) {\n const template = data.template as SiteDocument;\n if (!Array.isArray(template.pages)) {\n template.pages = [];\n }\n if (\n template.schemaVersion !== 2 &&\n template.schemaVersion !== \"2\"\n ) {\n template.schemaVersion = 2;\n }\n setDocument(template);\n } else {\n throw new Error(\n \"Formato de template legado não suportado. Por favor, recrie o site.\",\n );\n }\n } else {\n setDocument(null);\n }\n\n if (data.publishedHtml && hasBodyContent(data.publishedHtml)) {\n setPublishedHtml(data.publishedHtml);\n } else {\n setPublishedHtml(null);\n }\n\n if (!data.template && !data.publishedHtml) {\n throw new Error(\"Template não encontrado\");\n }\n } catch (err) {\n if (!stale) {\n setError(\n err instanceof Error\n ? err.message\n : \"Erro ao carregar landing page\",\n );\n }\n } finally {\n if (!stale) {\n setIsLoading(false);\n }\n }\n })();\n\n return () => {\n stale = true;\n };\n }, [siteId, apiBaseUrl, projectId]);\n\n // Hydrate pages when document + contentProviders are available.\n // Supports both: pages with explicit dataSource AND pages with blogPostGrid blocks.\n // Does NOT reset hydratedHtml at the start to avoid flash of mock data.\n // Only clears it when navigating to a page that doesn't need hydration.\n useEffect(() => {\n if (!document) {\n setHydratedHtml(null);\n return;\n }\n\n let stale = false;\n\n const pages = Array.isArray(document.pages) ? document.pages : [];\n const providerMap = buildProviderMap(contentProviders);\n\n if (providerMap.size === 0) {\n setHydratedHtml(null);\n return;\n }\n\n // Resolve the current page\n let resolvedPage: SitePage | undefined;\n let urlParams: Record<string, string> = {};\n\n if (pageSlug) {\n const exactPage = pages.find(\n (p) => p.slug === pageSlug || p.id === pageSlug,\n );\n if (exactPage) {\n resolvedPage = exactPage;\n } else {\n const match = matchDynamicPage(pages, pageSlug);\n if (match) {\n resolvedPage = match.page;\n urlParams = match.params;\n }\n }\n } else {\n resolvedPage = pages.find((p) => p.id === \"home\") ?? pages[0];\n }\n\n if (!resolvedPage) {\n setHydratedHtml(null);\n return;\n }\n\n // Check if page needs hydration:\n // 1. Has explicit dataSource (blog page, blog-post page)\n // 2. Has blogPostGrid blocks but no dataSource (home page with blog widget)\n const hasDataSource = !!resolvedPage.dataSource;\n const hasBlogBlocks = resolvedPage.structure?.some(\n (b) => b.type === \"blogPostGrid\",\n );\n\n if (!hasDataSource && !hasBlogBlocks) {\n setHydratedHtml(null);\n return;\n }\n\n // For pages without dataSource but with blog blocks, create synthetic dataSource\n let pageToHydrate = resolvedPage;\n if (!hasDataSource && hasBlogBlocks) {\n pageToHydrate = {\n ...resolvedPage,\n dataSource: { mode: \"list\" as const, provider: \"blog-posts\" },\n };\n }\n\n hydratePageWithContent(pageToHydrate, providerMap, urlParams)\n .then((hydratedPage) => {\n if (stale) return;\n const html = renderPageToHtml(\n hydratedPage,\n document,\n schoolSlug,\n pages,\n );\n setHydratedHtml(html ?? null);\n })\n .catch((err) => {\n if (!stale) {\n logger.error(\"Error hydrating page:\", err);\n setHydratedHtml(null);\n }\n });\n\n return () => {\n stale = true;\n };\n }, [document, pageSlug, contentProviders, schoolSlug]);\n\n if (isLoading) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>Carregando...</div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>{error || \"Landing page não encontrada\"}</div>\n </div>\n );\n }\n\n // Preferir renderização via template (client-side) quando disponível.\n // Isso garante que o viewer usa exatamente o mesmo exportPageToHtml() do editor,\n // evitando diferenças de hover effects, CSS, etc. entre editor e site publicado.\n // publishedHtml do servidor é usado apenas como fallback quando não há template.\n const isHomeRoute = !pageSlug || pageSlug === \"home\";\n if (publishedHtml && isHomeRoute && !document) {\n return (\n <iframe\n srcDoc={injectClickInterceptor(publishedHtml)}\n title=\"Site publicado\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n }\n\n // Renderizar documento (template) — mesmo pipeline do editor\n if (!document) {\n return null;\n }\n\n // Garantir que pages seja array (evita crash se API retornar formato inesperado)\n const pages = Array.isArray(document.pages) ? document.pages : [];\n\n if (pages.length === 0) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n padding: \"2rem\",\n textAlign: \"center\",\n }}\n >\n <div>Nenhuma página no site. Adicione páginas no editor.</div>\n </div>\n );\n }\n\n // If we have hydrated HTML from ContentProvider, use it\n if (hydratedHtml) {\n return (\n <iframe\n srcDoc={injectClickInterceptor(hydratedHtml)}\n title=\"Site\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n }\n\n // Resolver página por slug ou id; fallback para home\n // Also try dynamic page resolution\n let page =\n (pageSlug\n ? pages.find((p) => p.slug === pageSlug || p.id === pageSlug)\n : null) ??\n null;\n\n if (!page && pageSlug) {\n const match = matchDynamicPage(pages, pageSlug);\n if (match) {\n page = match.page;\n }\n }\n\n if (!page) {\n page = pages.find((p) => p.id === \"home\") ?? pages[0];\n }\n\n if (!page) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>Página não encontrada</div>\n </div>\n );\n }\n\n const html = renderPageToHtml(page, document, schoolSlug, pages);\n if (!html) {\n return (\n <div\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n textAlign: \"center\",\n }}\n >\n <div>Conteúdo da página vazio. Adicione blocos no editor.</div>\n </div>\n );\n }\n\n // Mesmo mecanismo do Preview (editor): iframe com srcdoc = HTML completo\n return (\n <iframe\n srcDoc={injectClickInterceptor(html)}\n title=\"Site\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n}\n\n/**\n * Generates HTML from a page using the standard export pipeline.\n * Extracted to reuse for both static and hydrated pages.\n */\nfunction renderPageToHtml(\n page: SitePage,\n document: SiteDocument,\n schoolSlug?: string,\n allPages?: SitePage[],\n): string | null {\n // Garantir structure para o export (evita erro se página vier sem structure)\n const pageWithStructure = {\n ...page,\n structure: Array.isArray(page.structure) ? page.structure : [],\n };\n\n // Garantir theme completo para o export (merge com default evita theme parcial quebrar CSS)\n const defaultDoc = createEmptySiteDocument(\"\");\n const rawTheme =\n document.theme && typeof document.theme === \"object\"\n ? document.theme\n : null;\n const theme = rawTheme\n ? {\n ...defaultThemeTokens,\n ...rawTheme,\n colors:\n rawTheme.colors && typeof rawTheme.colors === \"object\"\n ? { ...defaultThemeTokens.colors, ...rawTheme.colors }\n : defaultThemeTokens.colors,\n typography:\n rawTheme.typography && typeof rawTheme.typography === \"object\"\n ? { ...defaultThemeTokens.typography, ...rawTheme.typography }\n : defaultThemeTokens.typography,\n }\n : defaultDoc.theme;\n\n const documentWithTheme: SiteDocument = {\n ...document,\n schemaVersion: 2,\n theme,\n };\n\n // basePath para links (ex.: /site ou /site/escola/:slug)\n const basePath = schoolSlug ? `/site/escola/${schoolSlug}` : \"/site\";\n\n const pages = allPages ?? document.pages;\n const homePage = pages.find((p) => p.id === \"home\") ?? pages[0];\n const layoutFromPage =\n homePage && homePage.id !== pageWithStructure.id\n ? {\n ...homePage,\n structure: Array.isArray(homePage.structure)\n ? homePage.structure\n : [],\n }\n : undefined;\n\n try {\n const html = exportPageToHtml(\n pageWithStructure,\n documentWithTheme,\n true,\n basePath,\n layoutFromPage ? { layoutFromPage } : undefined,\n );\n\n if (!html || !html.trim()) {\n return null;\n }\n\n return html;\n } catch (err) {\n logger.error(\"Error generating HTML:\", err);\n return null;\n }\n}\n"],"names":["hasBodyContent","html","match","buildProviderMap","providers","map","p","LandingPageViewer","siteId","apiBaseUrl","projectId","pageSlug","schoolSlug","_schoolData","contentProviders","onNavigate","document","setDocument","useState","publishedHtml","setPublishedHtml","isLoading","setIsLoading","error","setError","hydratedHtml","setHydratedHtml","onNavigateRef","useRef","injectClickInterceptor","useCallback","script","useEffect","handleMessage","event","stale","response","data","schemaVersion","hasPages","template","err","pages","providerMap","resolvedPage","urlParams","exactPage","matchDynamicPage","hasDataSource","hasBlogBlocks","b","pageToHydrate","hydratePageWithContent","hydratedPage","renderPageToHtml","logger","jsx","page","allPages","pageWithStructure","defaultDoc","createEmptySiteDocument","rawTheme","theme","defaultThemeTokens","documentWithTheme","basePath","homePage","layoutFromPage","exportPageToHtml"],"mappings":"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"}
1
+ {"version":3,"file":"LandingPageViewer.js","sources":["../../src/viewer/LandingPageViewer.tsx"],"sourcesContent":["/**\n * Landing Page Viewer\n * Visualização pública da landing page.\n * Usa o mesmo mecanismo do Preview (editor): exportPageToHtml + iframe srcdoc.\n *\n * Supports dynamic pages via ContentProvider (Sprint 3):\n * - Optional `contentProviders` prop allows consumer to supply data providers\n * - Dynamic page resolution (e.g., \"blog/:slug\")\n * - Automatic content hydration before rendering\n */\n\nimport { useState, useEffect, useRef, useCallback } from \"react\";\nimport {\n SiteDocument,\n SitePage,\n exportPageToHtml,\n createEmptySiteDocument,\n defaultThemeTokens,\n} from \"../engine\";\nimport type { ContentProvider } from \"../engine/plugins/types\";\nimport { matchDynamicPage } from \"../engine/plugins/dynamicPageResolver\";\nimport {\n hydratePageWithContent,\n type ContentProviderMap,\n} from \"../engine/plugins/contentHydration\";\nimport { logger } from \"../utils/logger\";\n\n/** Verifica se o HTML tem conteúdo real no body (evita usar publishedHtml vazio) */\nfunction hasBodyContent(html: string): boolean {\n if (!html || typeof html !== \"string\") return false;\n const match = html.match(/<body[^>]*>([\\s\\S]*?)<\\/body>/i);\n const bodyInner = match ? match[1].trim() : \"\";\n return bodyInner.length > 50;\n}\n\nexport interface SchoolData {\n id: string;\n name: string;\n slug: string;\n logo_url?: string;\n}\n\ninterface LandingPageViewerProps {\n siteId: string;\n apiBaseUrl: string;\n projectId: string;\n /** Slug da página (ex.: avisos). Se não informado, usa home. */\n pageSlug?: string;\n /** Slug da escola no contexto /site/escola/:schoolSlug */\n schoolSlug?: string;\n /** Dados da escola para header/navbar dinâmico (quando em contexto escola) */\n schoolData?: SchoolData;\n /**\n * Content providers for dynamic pages (e.g., blog posts, products).\n * Supplied by the consumer project to connect plugin data to the viewer.\n */\n contentProviders?: ContentProvider[];\n /**\n * Callback for internal navigation (link clicks inside iframe).\n * Receives the href from clicked links. Consumer should use router navigation.\n */\n onNavigate?: (href: string) => void;\n}\n\n/**\n * Builds a ContentProviderMap from an array of providers.\n */\nfunction buildProviderMap(providers?: ContentProvider[]): ContentProviderMap {\n const map: ContentProviderMap = new Map();\n if (providers) {\n for (const p of providers) {\n map.set(p.type, p);\n }\n }\n return map;\n}\n\nexport function LandingPageViewer({\n siteId,\n apiBaseUrl,\n projectId,\n pageSlug,\n schoolSlug,\n schoolData: _schoolData, // reservado para header/navbar dinâmico (logo, nome da escola)\n contentProviders,\n onNavigate,\n}: LandingPageViewerProps) {\n const [document, setDocument] = useState<SiteDocument | null>(null);\n const [publishedHtml, setPublishedHtml] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [hydratedHtml, setHydratedHtml] = useState<string | null>(null);\n\n const onNavigateRef = useRef(onNavigate);\n onNavigateRef.current = onNavigate;\n\n // Inject click interceptor into iframe HTML so link clicks propagate to parent\n const injectClickInterceptor = useCallback((html: string): string => {\n const script = `<script>\n(function() {\n document.addEventListener('click', function(e) {\n var target = e.target;\n var anchor = target;\n while (anchor && anchor.tagName !== 'A') {\n anchor = anchor.parentElement;\n }\n if (anchor && anchor.tagName === 'A') {\n var href = anchor.getAttribute('href') || '';\n if (href && href !== '#' && !href.startsWith('javascript:')) {\n e.preventDefault();\n e.stopPropagation();\n window.parent.postMessage({ type: 'viewer-navigate', href: href }, '*');\n return;\n }\n }\n }, true);\n})();\n</script>`;\n if (html.includes(\"</body>\")) {\n return html.replace(\"</body>\", `${script}</body>`);\n }\n return html + script;\n }, []);\n\n // Listen for navigation messages from iframe\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === \"viewer-navigate\" && event.data?.href) {\n if (onNavigateRef.current) {\n onNavigateRef.current(event.data.href);\n }\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, []);\n\n // Load site document from API. Uses stale flag to prevent\n // React Strict Mode double-mount from causing duplicate state updates.\n useEffect(() => {\n let stale = false;\n\n setIsLoading(true);\n setError(null);\n\n (async () => {\n try {\n const response = await fetch(\n `${apiBaseUrl}/sites/${siteId}?projectId=${projectId}`,\n );\n if (!response.ok) {\n throw new Error(\"Landing page não encontrada\");\n }\n\n const data = await response.json();\n if (stale) return;\n\n if (data.template) {\n const schemaVersion = data.template.schemaVersion;\n const hasPages =\n data.template.pages && Array.isArray(data.template.pages);\n const isV2 =\n schemaVersion === 2 || schemaVersion === \"2\" || hasPages;\n\n if (isV2) {\n const template = data.template as SiteDocument;\n if (!Array.isArray(template.pages)) {\n template.pages = [];\n }\n if (\n template.schemaVersion !== 2 &&\n template.schemaVersion !== \"2\"\n ) {\n template.schemaVersion = 2;\n }\n setDocument(template);\n } else {\n throw new Error(\n \"Formato de template legado não suportado. Por favor, recrie o site.\",\n );\n }\n } else {\n setDocument(null);\n }\n\n if (data.publishedHtml && hasBodyContent(data.publishedHtml)) {\n setPublishedHtml(data.publishedHtml);\n } else {\n setPublishedHtml(null);\n }\n\n if (!data.template && !data.publishedHtml) {\n throw new Error(\"Template não encontrado\");\n }\n } catch (err) {\n if (!stale) {\n setError(\n err instanceof Error\n ? err.message\n : \"Erro ao carregar landing page\",\n );\n }\n } finally {\n if (!stale) {\n setIsLoading(false);\n }\n }\n })();\n\n return () => {\n stale = true;\n };\n }, [siteId, apiBaseUrl, projectId]);\n\n // Hydrate pages when document + contentProviders are available.\n // Supports both: pages with explicit dataSource AND pages with blogPostGrid blocks.\n // Does NOT reset hydratedHtml at the start to avoid flash of mock data.\n // Only clears it when navigating to a page that doesn't need hydration.\n useEffect(() => {\n if (!document) {\n setHydratedHtml(null);\n return;\n }\n\n let stale = false;\n\n const pages = Array.isArray(document.pages) ? document.pages : [];\n const providerMap = buildProviderMap(contentProviders);\n\n if (providerMap.size === 0) {\n setHydratedHtml(null);\n return;\n }\n\n // Resolve the current page\n let resolvedPage: SitePage | undefined;\n let urlParams: Record<string, string> = {};\n\n if (pageSlug) {\n const exactPage = pages.find(\n (p) => p.slug === pageSlug || p.id === pageSlug,\n );\n if (exactPage) {\n resolvedPage = exactPage;\n } else {\n const match = matchDynamicPage(pages, pageSlug);\n if (match) {\n resolvedPage = match.page;\n urlParams = match.params;\n }\n }\n } else {\n resolvedPage = pages.find((p) => p.id === \"home\") ?? pages[0];\n }\n\n if (!resolvedPage) {\n setHydratedHtml(null);\n return;\n }\n\n // Check if page needs hydration:\n // 1. Has explicit dataSource (blog page, blog-post page)\n // 2. Has blogPostGrid blocks but no dataSource (home page with blog widget)\n const hasDataSource = !!resolvedPage.dataSource;\n const hasBlogBlocks = resolvedPage.structure?.some(\n (b) => b.type === \"blogPostGrid\",\n );\n\n if (!hasDataSource && !hasBlogBlocks) {\n setHydratedHtml(null);\n return;\n }\n\n // For pages without dataSource but with blog blocks, create synthetic dataSource\n let pageToHydrate = resolvedPage;\n if (!hasDataSource && hasBlogBlocks) {\n pageToHydrate = {\n ...resolvedPage,\n dataSource: { mode: \"list\" as const, provider: \"blog-posts\" },\n };\n }\n\n hydratePageWithContent(pageToHydrate, providerMap, urlParams)\n .then((hydratedPage) => {\n if (stale) return;\n\n // useCache: false — hydrated page has different block props than the\n // cached static render. Without this, exportPageToHtml returns the\n // cached static HTML (same page.id + docHash = same cache key).\n const html = renderPageToHtml(\n hydratedPage,\n document,\n schoolSlug,\n pages,\n false,\n );\n\n setHydratedHtml(html ?? null);\n })\n .catch((err) => {\n if (!stale) {\n logger.error(\"Error in content hydration:\", err);\n setHydratedHtml(null);\n }\n });\n\n return () => {\n stale = true;\n };\n }, [document, pageSlug, contentProviders, schoolSlug]);\n\n if (isLoading) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>Carregando...</div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>{error || \"Landing page não encontrada\"}</div>\n </div>\n );\n }\n\n // Preferir renderização via template (client-side) quando disponível.\n // Isso garante que o viewer usa exatamente o mesmo exportPageToHtml() do editor,\n // evitando diferenças de hover effects, CSS, etc. entre editor e site publicado.\n // publishedHtml do servidor é usado apenas como fallback quando não há template.\n const isHomeRoute = !pageSlug || pageSlug === \"home\";\n if (publishedHtml && isHomeRoute && !document) {\n return (\n <iframe\n srcDoc={injectClickInterceptor(publishedHtml)}\n title=\"Site publicado\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n }\n\n // Renderizar documento (template) — mesmo pipeline do editor\n if (!document) {\n return null;\n }\n\n // Garantir que pages seja array (evita crash se API retornar formato inesperado)\n const pages = Array.isArray(document.pages) ? document.pages : [];\n\n if (pages.length === 0) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n padding: \"2rem\",\n textAlign: \"center\",\n }}\n >\n <div>Nenhuma página no site. Adicione páginas no editor.</div>\n </div>\n );\n }\n\n // If we have hydrated HTML from ContentProvider, use it\n if (hydratedHtml) {\n return (\n <iframe\n srcDoc={injectClickInterceptor(hydratedHtml)}\n title=\"Site\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n }\n\n // Resolver página por slug ou id; fallback para home\n // Also try dynamic page resolution\n let page =\n (pageSlug\n ? pages.find((p) => p.slug === pageSlug || p.id === pageSlug)\n : null) ??\n null;\n\n if (!page && pageSlug) {\n const match = matchDynamicPage(pages, pageSlug);\n if (match) {\n page = match.page;\n }\n }\n\n if (!page) {\n page = pages.find((p) => p.id === \"home\") ?? pages[0];\n }\n\n if (!page) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n }}\n >\n <div>Página não encontrada</div>\n </div>\n );\n }\n\n const html = renderPageToHtml(page, document, schoolSlug, pages);\n if (!html) {\n return (\n <div\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n textAlign: \"center\",\n }}\n >\n <div>Conteúdo da página vazio. Adicione blocos no editor.</div>\n </div>\n );\n }\n\n // Mesmo mecanismo do Preview (editor): iframe com srcdoc = HTML completo\n return (\n <iframe\n srcDoc={injectClickInterceptor(html)}\n title=\"Site\"\n style={{\n width: \"100%\",\n minHeight: \"100vh\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n}\n\n/**\n * Generates HTML from a page using the standard export pipeline.\n * Extracted to reuse for both static and hydrated pages.\n *\n * @param useCache - Pass false for hydrated pages to bypass the export cache.\n * The cache key uses page.id + docHash, which is identical for static and\n * hydrated renders of the same page. Hydrated pages have different block\n * props (real data), so they must skip the cache to avoid getting stale HTML.\n */\nfunction renderPageToHtml(\n page: SitePage,\n document: SiteDocument,\n schoolSlug?: string,\n allPages?: SitePage[],\n useCache: boolean = true,\n): string | null {\n // Garantir structure para o export (evita erro se página vier sem structure)\n const pageWithStructure = {\n ...page,\n structure: Array.isArray(page.structure) ? page.structure : [],\n };\n\n // Garantir theme completo para o export (merge com default evita theme parcial quebrar CSS)\n const defaultDoc = createEmptySiteDocument(\"\");\n const rawTheme =\n document.theme && typeof document.theme === \"object\"\n ? document.theme\n : null;\n const theme = rawTheme\n ? {\n ...defaultThemeTokens,\n ...rawTheme,\n colors:\n rawTheme.colors && typeof rawTheme.colors === \"object\"\n ? { ...defaultThemeTokens.colors, ...rawTheme.colors }\n : defaultThemeTokens.colors,\n typography:\n rawTheme.typography && typeof rawTheme.typography === \"object\"\n ? { ...defaultThemeTokens.typography, ...rawTheme.typography }\n : defaultThemeTokens.typography,\n }\n : defaultDoc.theme;\n\n const documentWithTheme: SiteDocument = {\n ...document,\n schemaVersion: 2,\n theme,\n };\n\n // basePath para links (ex.: /site ou /site/escola/:slug)\n const basePath = schoolSlug ? `/site/escola/${schoolSlug}` : \"/site\";\n\n const pages = allPages ?? document.pages;\n const homePage = pages.find((p) => p.id === \"home\") ?? pages[0];\n const layoutFromPage =\n homePage && homePage.id !== pageWithStructure.id\n ? {\n ...homePage,\n structure: Array.isArray(homePage.structure)\n ? homePage.structure\n : [],\n }\n : undefined;\n\n try {\n const html = exportPageToHtml(\n pageWithStructure,\n documentWithTheme,\n useCache,\n basePath,\n layoutFromPage ? { layoutFromPage } : undefined,\n );\n\n if (!html || !html.trim()) {\n return null;\n }\n\n return html;\n } catch (err) {\n logger.error(\"Error generating HTML:\", err);\n return null;\n }\n}\n"],"names":["hasBodyContent","html","match","buildProviderMap","providers","map","p","LandingPageViewer","siteId","apiBaseUrl","projectId","pageSlug","schoolSlug","_schoolData","contentProviders","onNavigate","document","setDocument","useState","publishedHtml","setPublishedHtml","isLoading","setIsLoading","error","setError","hydratedHtml","setHydratedHtml","onNavigateRef","useRef","injectClickInterceptor","useCallback","script","useEffect","handleMessage","event","stale","response","data","schemaVersion","hasPages","template","err","pages","providerMap","resolvedPage","urlParams","exactPage","matchDynamicPage","hasDataSource","hasBlogBlocks","b","pageToHydrate","hydratePageWithContent","hydratedPage","renderPageToHtml","logger","jsx","page","allPages","useCache","pageWithStructure","defaultDoc","createEmptySiteDocument","rawTheme","theme","defaultThemeTokens","documentWithTheme","basePath","homePage","layoutFromPage","exportPageToHtml"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brunoalz/smartgesti-site-editor",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Site editor component for SmartGesti platform",