@brunoalz/smartgesti-site-editor 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/plugins/builtin/blog/manifest.d.ts.map +1 -1
- package/dist/engine/plugins/builtin/blog/manifest.js +73 -55
- package/dist/engine/plugins/builtin/blog/manifest.js.map +1 -1
- package/dist/engine/registry/blocks/sections/blogPostGrid.js +4 -4
- package/dist/engine/registry/blocks/sections/blogPostGrid.js.map +1 -1
- package/dist/hooks/useNavbarAutoSync.d.ts.map +1 -1
- package/dist/hooks/useNavbarAutoSync.js +27 -15
- package/dist/hooks/useNavbarAutoSync.js.map +1 -1
- package/dist/utils/navbarSync.d.ts +3 -1
- package/dist/utils/navbarSync.d.ts.map +1 -1
- package/dist/utils/navbarSync.js +3 -3
- package/dist/utils/navbarSync.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAqFtD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAqFtD,eAAO,MAAM,UAAU,EAAE,kBA0XxB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { pluginRegistry as
|
|
2
|
-
import { logger as
|
|
3
|
-
const
|
|
1
|
+
import { pluginRegistry as f } from "../../pluginRegistry.js";
|
|
2
|
+
import { logger as d } from "../../../../utils/logger.js";
|
|
3
|
+
const u = "plugin-blog-home-grid", h = [
|
|
4
4
|
{
|
|
5
5
|
title: "Feira de Ciências 2026: Inovação e Criatividade",
|
|
6
6
|
excerpt: "Nossos alunos apresentaram projetos incríveis na Feira de Ciências deste ano. Confira os destaques e premiações!",
|
|
@@ -58,10 +58,10 @@ const p = "plugin-blog-home-grid", u = [
|
|
|
58
58
|
<p>Os três projetos finalistas representarão nossa escola na <strong>Feira Regional de Ciências</strong>, que acontecerá em março na capital. Os alunos já estão se preparando para levar suas apresentações a um público ainda maior.</p>
|
|
59
59
|
<p>Parabéns a todos os participantes, professores orientadores e famílias que apoiaram essa jornada de descobertas!</p>
|
|
60
60
|
`.trim();
|
|
61
|
-
function
|
|
62
|
-
return { ...JSON.parse(JSON.stringify(
|
|
61
|
+
function m(s, l) {
|
|
62
|
+
return { ...JSON.parse(JSON.stringify(s)), id: l };
|
|
63
63
|
}
|
|
64
|
-
const
|
|
64
|
+
const y = {
|
|
65
65
|
manifest: {
|
|
66
66
|
id: "blog",
|
|
67
67
|
version: "1.0.0",
|
|
@@ -128,39 +128,53 @@ const f = {
|
|
|
128
128
|
requiredPages: ["blog-listing", "blog-post"]
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
|
-
onActivate(
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
if (
|
|
135
|
-
const e =
|
|
136
|
-
|
|
131
|
+
onActivate(s) {
|
|
132
|
+
d.debug("Blog plugin activating...");
|
|
133
|
+
const l = new Set(s.pages.map((e) => e.id)), o = [...s.pages], t = s.pages.find((e) => e.slug === "home") || s.pages[0], n = t?.structure.find((e) => e.type === "navbar"), i = t?.structure.find((e) => e.type === "footer");
|
|
134
|
+
if (t && n) {
|
|
135
|
+
const e = o.findIndex((r) => r.id === t.id);
|
|
136
|
+
if (e >= 0) {
|
|
137
|
+
const r = n.props, a = Array.isArray(r.links) ? [...r.links] : [];
|
|
138
|
+
if (!a.some(
|
|
139
|
+
(p) => p.href === "/p/blog"
|
|
140
|
+
)) {
|
|
141
|
+
const p = a.length > 0 ? a.length - 1 : 0;
|
|
142
|
+
a.splice(p, 0, { text: "Blog", href: "/p/blog" });
|
|
143
|
+
const b = o[e].structure.map((c) => c.id === n.id ? { ...c, props: { ...c.props, links: a } } : c);
|
|
144
|
+
o[e] = { ...o[e], structure: b }, d.debug("Blog link added to home navbar"), n.props = { ...r, links: a };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (t) {
|
|
149
|
+
const e = o.findIndex((a) => a.id === t.id), r = t.structure.some(
|
|
150
|
+
(a) => a.id === u
|
|
137
151
|
);
|
|
138
|
-
if (e >= 0 && !
|
|
139
|
-
const
|
|
140
|
-
id:
|
|
152
|
+
if (e >= 0 && !r) {
|
|
153
|
+
const a = {
|
|
154
|
+
id: u,
|
|
141
155
|
type: "blogPostGrid",
|
|
142
156
|
props: {
|
|
143
157
|
title: "Blog",
|
|
144
158
|
subtitle: "Últimas publicações",
|
|
145
159
|
columns: 3,
|
|
146
|
-
cards:
|
|
160
|
+
cards: h,
|
|
147
161
|
variant: "default",
|
|
148
162
|
showViewAll: !0,
|
|
149
163
|
viewAllText: "Ver todos os posts",
|
|
150
164
|
viewAllHref: "/site/p/blog"
|
|
151
165
|
}
|
|
152
|
-
},
|
|
166
|
+
}, g = [...o[e].structure], p = g.findIndex(
|
|
153
167
|
(b) => b.type === "footer"
|
|
154
168
|
);
|
|
155
|
-
|
|
156
|
-
...
|
|
157
|
-
structure:
|
|
158
|
-
},
|
|
169
|
+
p >= 0 ? g.splice(p, 0, a) : g.push(a), o[e] = {
|
|
170
|
+
...o[e],
|
|
171
|
+
structure: g
|
|
172
|
+
}, d.debug("Blog section injected into home page");
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
|
-
if (!
|
|
175
|
+
if (!l.has("blog")) {
|
|
162
176
|
const e = [];
|
|
163
|
-
|
|
177
|
+
n && e.push(m(n, "blog-page-navbar")), e.push({
|
|
164
178
|
id: "blog-page-hero",
|
|
165
179
|
type: "hero",
|
|
166
180
|
props: {
|
|
@@ -188,9 +202,9 @@ const f = {
|
|
|
188
202
|
type: "blogCategoryFilter",
|
|
189
203
|
props: {
|
|
190
204
|
title: "",
|
|
191
|
-
categories:
|
|
192
|
-
name:
|
|
193
|
-
slug:
|
|
205
|
+
categories: h.map((r) => ({
|
|
206
|
+
name: r.category,
|
|
207
|
+
slug: r.category.toLowerCase().replace(/\s+/g, "-"),
|
|
194
208
|
count: 1
|
|
195
209
|
})),
|
|
196
210
|
variant: "chips",
|
|
@@ -206,13 +220,13 @@ const f = {
|
|
|
206
220
|
title: "",
|
|
207
221
|
subtitle: "",
|
|
208
222
|
columns: 3,
|
|
209
|
-
cards:
|
|
223
|
+
cards: h,
|
|
210
224
|
variant: "default",
|
|
211
225
|
showViewAll: !1,
|
|
212
226
|
viewAllText: "Ver todos",
|
|
213
|
-
viewAllHref: "/blog"
|
|
227
|
+
viewAllHref: "/site/p/blog"
|
|
214
228
|
}
|
|
215
|
-
}),
|
|
229
|
+
}), i && e.push(m(i, "blog-page-footer")), o.push({
|
|
216
230
|
id: "blog",
|
|
217
231
|
name: "Blog",
|
|
218
232
|
slug: "blog",
|
|
@@ -223,11 +237,11 @@ const f = {
|
|
|
223
237
|
provider: "blog-posts",
|
|
224
238
|
mode: "list"
|
|
225
239
|
}
|
|
226
|
-
}),
|
|
240
|
+
}), d.debug("Blog listing page created");
|
|
227
241
|
}
|
|
228
|
-
if (!
|
|
242
|
+
if (!l.has("blog-post")) {
|
|
229
243
|
const e = [];
|
|
230
|
-
|
|
244
|
+
n && e.push(m(n, "post-page-navbar")), e.push({
|
|
231
245
|
id: "blog-detail-main",
|
|
232
246
|
type: "blogPostDetail",
|
|
233
247
|
props: {
|
|
@@ -246,7 +260,7 @@ const f = {
|
|
|
246
260
|
showReadingTime: !0,
|
|
247
261
|
contentMaxWidth: "720px"
|
|
248
262
|
}
|
|
249
|
-
}),
|
|
263
|
+
}), i && e.push(m(i, "post-page-footer")), o.push({
|
|
250
264
|
id: "blog-post",
|
|
251
265
|
name: "Post",
|
|
252
266
|
slug: "blog/:slug",
|
|
@@ -263,43 +277,47 @@ const f = {
|
|
|
263
277
|
lockedStructure: !0,
|
|
264
278
|
nonRemovable: !0
|
|
265
279
|
}
|
|
266
|
-
}),
|
|
280
|
+
}), d.debug("Blog post detail page created");
|
|
267
281
|
}
|
|
268
282
|
return {
|
|
269
|
-
...
|
|
270
|
-
pages:
|
|
283
|
+
...s,
|
|
284
|
+
pages: o
|
|
271
285
|
};
|
|
272
286
|
},
|
|
273
|
-
onDeactivate(
|
|
274
|
-
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
(
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
onDeactivate(s) {
|
|
288
|
+
d.debug("Blog plugin deactivating...");
|
|
289
|
+
const l = s.pages.filter((o) => o.pluginId !== "blog").map((o) => {
|
|
290
|
+
let t = o.structure;
|
|
291
|
+
return t.some(
|
|
292
|
+
(i) => i.id === u
|
|
293
|
+
) && (t = t.filter(
|
|
294
|
+
(i) => i.id !== u
|
|
295
|
+
)), t = t.map((i) => {
|
|
296
|
+
if (i.type !== "navbar") return i;
|
|
297
|
+
const e = i.props, r = Array.isArray(e.links) ? e.links : [], a = r.filter((g) => g.href !== "/p/blog");
|
|
298
|
+
return a.length !== r.length ? { ...i, props: { ...e, links: a } } : i;
|
|
299
|
+
}), t !== o.structure ? { ...o, structure: t } : o;
|
|
300
|
+
});
|
|
301
|
+
return d.debug(
|
|
302
|
+
`Removed ${s.pages.length - l.length} blog page(s) and injected section`
|
|
285
303
|
), {
|
|
286
|
-
...
|
|
287
|
-
pages:
|
|
304
|
+
...s,
|
|
305
|
+
pages: l
|
|
288
306
|
};
|
|
289
307
|
},
|
|
290
|
-
getEditorRestrictions(
|
|
291
|
-
if (
|
|
308
|
+
getEditorRestrictions(s) {
|
|
309
|
+
if (s === "blogPostDetail")
|
|
292
310
|
return {
|
|
293
311
|
lockedFields: ["content", "date"]
|
|
294
312
|
};
|
|
295
|
-
if (
|
|
313
|
+
if (s === "blogCategoryFilter")
|
|
296
314
|
return {
|
|
297
315
|
lockedFields: ["categories"]
|
|
298
316
|
};
|
|
299
317
|
}
|
|
300
318
|
};
|
|
301
|
-
|
|
319
|
+
f.register(y);
|
|
302
320
|
export {
|
|
303
|
-
|
|
321
|
+
y as blogPlugin
|
|
304
322
|
};
|
|
305
323
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"sourcesContent":["/**\n * Blog Plugin Manifest\n * Plugin para blog com posts, categorias e tags.\n *\n * onActivate:\n * 1. Injeta seção blogPostGrid na home page (antes do footer)\n * 2. Cria página \"Blog\" com navbar + grid de posts + footer\n * 3. Cria página \"Post\" com navbar + detalhe do post + footer\n *\n * onDeactivate:\n * 1. Remove a seção injetada na home page\n * 2. Remove as páginas do plugin\n */\n\nimport type { PluginRegistration } from \"../../types\";\nimport type { SiteDocument, Block, BlockType } from \"../../../schema/siteDocument\";\nimport { pluginRegistry } from \"../../pluginRegistry\";\nimport { logger } from \"../../../../utils/logger\";\n\n// ─── ID usado para a seção de blog injetada na home page ───\nconst BLOG_HOME_SECTION_ID = \"plugin-blog-home-grid\";\n\n// ─── Sample blog cards para preview ───\nconst SAMPLE_BLOG_CARDS = [\n {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n excerpt:\n \"Nossos alunos apresentaram projetos incríveis na Feira de Ciências deste ano. Confira os destaques e premiações!\",\n image:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=800&h=400&fit=crop\",\n category: \"Eventos\",\n date: \"05 Fev 2026\",\n linkHref: \"/site/p/blog/feira-de-ciencias-2026\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Matrículas Abertas para o Segundo Semestre\",\n excerpt:\n \"Garanta a vaga do seu filho na melhor escola da região. Condições especiais para matrículas antecipadas.\",\n image:\n \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2026\",\n linkHref: \"/site/p/blog/matriculas-segundo-semestre\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Preparar seu Filho para o Ano Letivo\",\n excerpt:\n \"Dicas práticas para uma transição tranquila e um início de ano produtivo para toda a família.\",\n image:\n \"https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"28 Jan 2026\",\n linkHref: \"/site/p/blog/dicas-preparar-ano-letivo\",\n linkText: \"Ler mais\",\n },\n];\n\n// ─── Conteúdo HTML rico para o post de exemplo ───\nconst SAMPLE_POST_CONTENT = `\n<h2>O que é a Feira de Ciências?</h2>\n<p>A Feira de Ciências é um evento anual que celebra a curiosidade, a pesquisa e a criatividade dos nossos alunos. Nesta edição especial de 2026, recebemos mais de <strong>500 visitantes</strong> e contamos com a participação de todas as turmas do Ensino Fundamental e Médio.</p>\n<p>Este ano, o tema central foi <em>\"Ciência e Sustentabilidade\"</em>, incentivando os estudantes a desenvolverem projetos que aliassem inovação tecnológica com responsabilidade ambiental.</p>\n\n<h2>Destaques da Edição 2026</h2>\n<p>Entre os mais de 50 projetos apresentados, alguns se destacaram pela originalidade e impacto:</p>\n<ul>\n <li><strong>Jardim Sustentável Inteligente</strong> — Alunos do 5º ano desenvolveram um sistema de irrigação automática usando sensores de umidade e placa Arduino.</li>\n <li><strong>Robótica Educacional</strong> — A turma do 8º ano criou um robô que auxilia no ensino de matemática para crianças do 1º ao 3º ano.</li>\n <li><strong>Energia Solar na Escola</strong> — Projeto do 2º ano do Ensino Médio demonstrou como painéis solares poderiam reduzir em 40% o consumo de energia da escola.</li>\n</ul>\n\n<blockquote>\n <p>\"A Feira de Ciências é um dos momentos mais importantes do nosso calendário escolar. Ver a dedicação e o brilho nos olhos dos alunos ao apresentarem seus projetos nos enche de orgulho e nos motiva a continuar investindo em educação de qualidade.\"</p>\n <p><strong>— Prof. Maria Silva, Coordenadora Pedagógica</strong></p>\n</blockquote>\n\n<h2>Premiações</h2>\n<p>O júri, composto por professores universitários e profissionais da área de tecnologia, selecionou os três melhores projetos:</p>\n<ol>\n <li><strong>1º Lugar:</strong> Jardim Sustentável Inteligente (5º ano)</li>\n <li><strong>2º Lugar:</strong> Energia Solar na Escola (2º EM)</li>\n <li><strong>3º Lugar:</strong> Robótica Educacional (8º ano)</li>\n</ol>\n\n<h2>Próximos Passos</h2>\n<p>Os três projetos finalistas representarão nossa escola na <strong>Feira Regional de Ciências</strong>, que acontecerá em março na capital. Os alunos já estão se preparando para levar suas apresentações a um público ainda maior.</p>\n<p>Parabéns a todos os participantes, professores orientadores e famílias que apoiaram essa jornada de descobertas!</p>\n`.trim();\n\n/**\n * Deep-clone um bloco com novo ID\n */\nfunction cloneBlock(block: Block, newId: string): Block {\n const cloned: Block = JSON.parse(JSON.stringify(block));\n return { ...cloned, id: newId };\n}\n\nexport const blogPlugin: PluginRegistration = {\n manifest: {\n id: \"blog\",\n version: \"1.0.0\",\n name: \"Blog\",\n description: \"Blog com posts, categorias e tags\",\n icon: \"FileText\",\n\n capabilities: {\n blocks: [\"blogPostCard\", \"blogPostGrid\", \"blogPostDetail\", \"blogCategoryFilter\", \"blogSearchBar\"],\n\n pageTemplates: [\n {\n id: \"blog-listing\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n },\n {\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n lockedStructure: true,\n nonRemovable: true,\n },\n },\n ],\n\n dataSchemas: [\n {\n type: \"blog-post\",\n label: \"Blog Post\",\n fields: [\n { name: \"title\", type: \"string\", required: true, label: \"Title\" },\n { name: \"slug\", type: \"string\", required: true, label: \"Slug\" },\n { name: \"excerpt\", type: \"string\", label: \"Excerpt\" },\n { name: \"content\", type: \"richtext\", required: true, label: \"Content\" },\n { name: \"featuredImage\", type: \"image\", label: \"Featured Image\" },\n { name: \"category\", type: \"string\", label: \"Category\" },\n { name: \"tags\", type: \"array\", label: \"Tags\" },\n { name: \"authorVariant\", type: \"string\", label: \"Author Variant\" },\n { name: \"readingTime\", type: \"number\", label: \"Reading Time\" },\n { name: \"metaTitle\", type: \"string\", label: \"Meta Title (SEO)\" },\n { name: \"metaDescription\", type: \"string\", label: \"Meta Description (SEO)\" },\n { name: \"ogImage\", type: \"image\", label: \"Open Graph Image\" },\n ],\n },\n ],\n\n contentProviders: [\"blog-posts\", \"blog-categories\"],\n },\n\n restrictions: {\n lockedFields: {\n blogPostDetail: [\"content\", \"date\"],\n },\n requiredPages: [\"blog-listing\", \"blog-post\"],\n },\n },\n\n onActivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin activating...\");\n\n const existingPageIds = new Set(document.pages.map((p) => p.id));\n const newPages = [...document.pages];\n\n // ── Encontrar home page para clonar navbar/footer ──\n const homePage =\n document.pages.find((p) => p.slug === \"home\") || document.pages[0];\n\n const homeNavbar = homePage?.structure.find((b) => b.type === \"navbar\");\n const homeFooter = homePage?.structure.find((b) => b.type === \"footer\");\n\n // ── 1. Injetar seção de blog na home page (antes do footer) ──\n if (homePage) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n const alreadyInjected = homePage.structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n\n if (homeIdx >= 0 && !alreadyInjected) {\n const blogHomeSection: Block = {\n id: BLOG_HOME_SECTION_ID,\n type: \"blogPostGrid\",\n props: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: true,\n viewAllText: \"Ver todos os posts\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block;\n\n const updatedStructure = [...newPages[homeIdx].structure];\n const footerIdx = updatedStructure.findIndex(\n (b) => b.type === \"footer\",\n );\n\n if (footerIdx >= 0) {\n updatedStructure.splice(footerIdx, 0, blogHomeSection);\n } else {\n updatedStructure.push(blogHomeSection);\n }\n\n newPages[homeIdx] = {\n ...newPages[homeIdx],\n structure: updatedStructure,\n };\n logger.debug(\"Blog section injected into home page\");\n }\n }\n\n // ── 2. Criar página \"Blog\" (listagem completa) ──\n if (!existingPageIds.has(\"blog\")) {\n const blogPageStructure: Block[] = [];\n\n // Navbar clonada da home\n if (homeNavbar) {\n blogPageStructure.push(cloneBlock(homeNavbar, \"blog-page-navbar\"));\n }\n\n // Hero banner do blog\n blogPageStructure.push({\n id: \"blog-page-hero\",\n type: \"hero\",\n props: {\n title: \"Blog\",\n subtitle: \"Novidades & Publicações\",\n description:\n \"Acompanhe as últimas novidades, eventos e conquistas da nossa comunidade escolar.\",\n variant: \"centered\",\n align: \"center\",\n overlay: true,\n overlayColor: \"rgba(79, 70, 229, 0.9)\",\n background: \"#4f46e5\",\n minHeight: \"280px\",\n },\n } as Block);\n\n // Search bar\n blogPageStructure.push({\n id: \"blog-search-bar\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Category filter\n blogPageStructure.push({\n id: \"blog-category-filter\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"chips\",\n showCount: false,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Grid de posts\n blogPageStructure.push({\n id: \"blog-grid-main\",\n type: \"blogPostGrid\",\n props: {\n title: \"\",\n subtitle: \"\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/blog\",\n },\n } as Block);\n\n // Footer clonado da home\n if (homeFooter) {\n blogPageStructure.push(cloneBlock(homeFooter, \"blog-page-footer\"));\n }\n\n newPages.push({\n id: \"blog\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-listing\",\n structure: blogPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n });\n logger.debug(\"Blog listing page created\");\n }\n\n // ── 3. Criar página \"Post\" (detalhe) ──\n if (!existingPageIds.has(\"blog-post\")) {\n const postPageStructure: Block[] = [];\n\n if (homeNavbar) {\n postPageStructure.push(cloneBlock(homeNavbar, \"post-page-navbar\"));\n }\n\n postPageStructure.push({\n id: \"blog-detail-main\",\n type: \"blogPostDetail\",\n props: {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n content: SAMPLE_POST_CONTENT,\n featuredImage:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=1200&h=600&fit=crop\",\n date: \"05 Fev 2026\",\n category: \"Eventos\",\n authorVariant: \"inline\",\n readingTime: \"5 min de leitura\",\n tags: [\"Feira de Ciências\", \"Eventos\", \"Sustentabilidade\", \"Projetos\"],\n showFeaturedImage: true,\n showAuthor: true,\n showDate: true,\n showTags: true,\n showReadingTime: true,\n contentMaxWidth: \"720px\",\n },\n } as Block);\n\n if (homeFooter) {\n postPageStructure.push(cloneBlock(homeFooter, \"post-page-footer\"));\n }\n\n newPages.push({\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-post\",\n isDynamic: true,\n structure: postPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n lockedStructure: true,\n nonRemovable: true,\n },\n });\n logger.debug(\"Blog post detail page created\");\n }\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n onDeactivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin deactivating...\");\n\n const newPages = document.pages\n // Remover páginas do plugin\n .filter((page) => page.pluginId !== \"blog\")\n // Remover seção de blog injetada na home page\n .map((page) => {\n const hasInjected = page.structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n if (hasInjected) {\n return {\n ...page,\n structure: page.structure.filter(\n (b) => b.id !== BLOG_HOME_SECTION_ID,\n ),\n };\n }\n return page;\n });\n\n logger.debug(\n `Removed ${document.pages.length - newPages.length} blog page(s) and injected section`,\n );\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n getEditorRestrictions(blockType: BlockType) {\n if (blockType === \"blogPostDetail\") {\n return {\n lockedFields: [\"content\", \"date\"],\n };\n }\n if (blockType === \"blogCategoryFilter\") {\n return {\n lockedFields: [\"categories\"],\n };\n }\n return undefined;\n },\n};\n\n// Auto-registrar o plugin (side effect — como os blocos fazem com componentRegistry)\npluginRegistry.register(blogPlugin);\n"],"names":["BLOG_HOME_SECTION_ID","SAMPLE_BLOG_CARDS","SAMPLE_POST_CONTENT","cloneBlock","block","newId","blogPlugin","document","logger","existingPageIds","p","newPages","homePage","homeNavbar","b","homeFooter","homeIdx","alreadyInjected","blogHomeSection","updatedStructure","footerIdx","blogPageStructure","c","postPageStructure","page","blockType","pluginRegistry"],"mappings":";;AAoBA,MAAMA,IAAuB,yBAGvBC,IAAoB;AAAA,EACxB;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAEd,GAGMC,IAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6B1B,KAAA;AAKF,SAASC,EAAWC,GAAcC,GAAsB;AAEtD,SAAO,EAAE,GADa,KAAK,MAAM,KAAK,UAAUD,CAAK,CAAC,GAClC,IAAIC,EAAA;AAC1B;AAEO,MAAMC,IAAiC;AAAA,EAC5C,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IAEN,cAAc;AAAA,MACZ,QAAQ,CAAC,gBAAgB,gBAAgB,kBAAkB,sBAAsB,eAAe;AAAA,MAEhG,eAAe;AAAA,QACb;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW,CAAA;AAAA,UACX,YAAY;AAAA,YACV,UAAU;AAAA,YACV,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,QAEF;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW,CAAA;AAAA,UACX,YAAY;AAAA,YACV,UAAU;AAAA,YACV,MAAM;AAAA,YACN,cAAc,EAAE,MAAM,QAAA;AAAA,UAAQ;AAAA,UAEhC,kBAAkB;AAAA,YAChB,iBAAiB;AAAA,YACjB,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,MAGF,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,YACN,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,IAAM,OAAO,QAAA;AAAA,YACxD,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,IAAM,OAAO,OAAA;AAAA,YACvD,EAAE,MAAM,WAAW,MAAM,UAAU,OAAO,UAAA;AAAA,YAC1C,EAAE,MAAM,WAAW,MAAM,YAAY,UAAU,IAAM,OAAO,UAAA;AAAA,YAC5D,EAAE,MAAM,iBAAiB,MAAM,SAAS,OAAO,iBAAA;AAAA,YAC/C,EAAE,MAAM,YAAY,MAAM,UAAU,OAAO,WAAA;AAAA,YAC3C,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,OAAA;AAAA,YACtC,EAAE,MAAM,iBAAiB,MAAM,UAAU,OAAO,iBAAA;AAAA,YAChD,EAAE,MAAM,eAAe,MAAM,UAAU,OAAO,eAAA;AAAA,YAC9C,EAAE,MAAM,aAAa,MAAM,UAAU,OAAO,mBAAA;AAAA,YAC5C,EAAE,MAAM,mBAAmB,MAAM,UAAU,OAAO,yBAAA;AAAA,YAClD,EAAE,MAAM,WAAW,MAAM,SAAS,OAAO,mBAAA;AAAA,UAAmB;AAAA,QAC9D;AAAA,MACF;AAAA,MAGF,kBAAkB,CAAC,cAAc,iBAAiB;AAAA,IAAA;AAAA,IAGpD,cAAc;AAAA,MACZ,cAAc;AAAA,QACZ,gBAAgB,CAAC,WAAW,MAAM;AAAA,MAAA;AAAA,MAEpC,eAAe,CAAC,gBAAgB,WAAW;AAAA,IAAA;AAAA,EAC7C;AAAA,EAGF,WAAWC,GAAsC;AAC/C,IAAAC,EAAO,MAAM,2BAA2B;AAExC,UAAMC,IAAkB,IAAI,IAAIF,EAAS,MAAM,IAAI,CAACG,MAAMA,EAAE,EAAE,CAAC,GACzDC,IAAW,CAAC,GAAGJ,EAAS,KAAK,GAG7BK,IACJL,EAAS,MAAM,KAAK,CAACG,MAAMA,EAAE,SAAS,MAAM,KAAKH,EAAS,MAAM,CAAC,GAE7DM,IAAaD,GAAU,UAAU,KAAK,CAACE,MAAMA,EAAE,SAAS,QAAQ,GAChEC,IAAaH,GAAU,UAAU,KAAK,CAACE,MAAMA,EAAE,SAAS,QAAQ;AAGtE,QAAIF,GAAU;AACZ,YAAMI,IAAUL,EAAS,UAAU,CAACD,MAAMA,EAAE,OAAOE,EAAS,EAAE,GACxDK,IAAkBL,EAAS,UAAU;AAAA,QACzC,CAACE,MAAMA,EAAE,OAAOd;AAAA,MAAA;AAGlB,UAAIgB,KAAW,KAAK,CAACC,GAAiB;AACpC,cAAMC,IAAyB;AAAA,UAC7B,IAAIlB;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,SAAS;AAAA,YACT,OAAOC;AAAA,YACP,SAAS;AAAA,YACT,aAAa;AAAA,YACb,aAAa;AAAA,YACb,aAAa;AAAA,UAAA;AAAA,QACf,GAGIkB,IAAmB,CAAC,GAAGR,EAASK,CAAO,EAAE,SAAS,GAClDI,IAAYD,EAAiB;AAAA,UACjC,CAAC,MAAM,EAAE,SAAS;AAAA,QAAA;AAGpB,QAAIC,KAAa,IACfD,EAAiB,OAAOC,GAAW,GAAGF,CAAe,IAErDC,EAAiB,KAAKD,CAAe,GAGvCP,EAASK,CAAO,IAAI;AAAA,UAClB,GAAGL,EAASK,CAAO;AAAA,UACnB,WAAWG;AAAA,QAAA,GAEbX,EAAO,MAAM,sCAAsC;AAAA,MACrD;AAAA,IACF;AAGA,QAAI,CAACC,EAAgB,IAAI,MAAM,GAAG;AAChC,YAAMY,IAA6B,CAAA;AAGnC,MAAIR,KACFQ,EAAkB,KAAKlB,EAAWU,GAAY,kBAAkB,CAAC,GAInEQ,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,aACE;AAAA,UACF,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,UACT,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVA,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVA,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,YAAYpB,EAAkB,IAAI,CAACqB,OAAO;AAAA,YACxC,MAAMA,EAAE;AAAA,YACR,MAAMA,EAAE,SAAS,cAAc,QAAQ,QAAQ,GAAG;AAAA,YAClD,OAAO;AAAA,UAAA,EACP;AAAA,UACF,SAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVD,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,SAAS;AAAA,UACT,OAAOpB;AAAA,UACP,SAAS;AAAA,UACT,aAAa;AAAA,UACb,aAAa;AAAA,UACb,aAAa;AAAA,QAAA;AAAA,MACf,CACQ,GAGNc,KACFM,EAAkB,KAAKlB,EAAWY,GAAY,kBAAkB,CAAC,GAGnEJ,EAAS,KAAK;AAAA,QACZ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,WAAWU;AAAA,QACX,YAAY;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,QAAA;AAAA,MACR,CACD,GACDb,EAAO,MAAM,2BAA2B;AAAA,IAC1C;AAGA,QAAI,CAACC,EAAgB,IAAI,WAAW,GAAG;AACrC,YAAMc,IAA6B,CAAA;AAEnC,MAAIV,KACFU,EAAkB,KAAKpB,EAAWU,GAAY,kBAAkB,CAAC,GAGnEU,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,SAASrB;AAAA,UACT,eACE;AAAA,UACF,MAAM;AAAA,UACN,UAAU;AAAA,UACV,eAAe;AAAA,UACf,aAAa;AAAA,UACb,MAAM,CAAC,qBAAqB,WAAW,oBAAoB,UAAU;AAAA,UACrE,mBAAmB;AAAA,UACnB,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,UAAU;AAAA,UACV,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,QAAA;AAAA,MACnB,CACQ,GAENa,KACFQ,EAAkB,KAAKpB,EAAWY,GAAY,kBAAkB,CAAC,GAGnEJ,EAAS,KAAK;AAAA,QACZ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,WAAWY;AAAA,QACX,YAAY;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,UACN,cAAc,EAAE,MAAM,QAAA;AAAA,QAAQ;AAAA,QAEhC,kBAAkB;AAAA,UAChB,iBAAiB;AAAA,UACjB,cAAc;AAAA,QAAA;AAAA,MAChB,CACD,GACDf,EAAO,MAAM,+BAA+B;AAAA,IAC9C;AAEA,WAAO;AAAA,MACL,GAAGD;AAAA,MACH,OAAOI;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,aAAaJ,GAAsC;AACjD,IAAAC,EAAO,MAAM,6BAA6B;AAE1C,UAAMG,IAAWJ,EAAS,MAEvB,OAAO,CAACiB,MAASA,EAAK,aAAa,MAAM,EAEzC,IAAI,CAACA,MACgBA,EAAK,UAAU;AAAA,MACjC,CAACV,MAAMA,EAAE,OAAOd;AAAA,IAAA,IAGT;AAAA,MACL,GAAGwB;AAAA,MACH,WAAWA,EAAK,UAAU;AAAA,QACxB,CAACV,MAAMA,EAAE,OAAOd;AAAA,MAAA;AAAA,IAClB,IAGGwB,CACR;AAEH,WAAAhB,EAAO;AAAA,MACL,WAAWD,EAAS,MAAM,SAASI,EAAS,MAAM;AAAA,IAAA,GAG7C;AAAA,MACL,GAAGJ;AAAA,MACH,OAAOI;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,sBAAsBc,GAAsB;AAC1C,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,WAAW,MAAM;AAAA,MAAA;AAGpC,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,YAAY;AAAA,MAAA;AAAA,EAIjC;AACF;AAGAC,EAAe,SAASpB,CAAU;"}
|
|
1
|
+
{"version":3,"file":"manifest.js","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"sourcesContent":["/**\n * Blog Plugin Manifest\n * Plugin para blog com posts, categorias e tags.\n *\n * onActivate:\n * 1. Injeta seção blogPostGrid na home page (antes do footer)\n * 2. Cria página \"Blog\" com navbar + grid de posts + footer\n * 3. Cria página \"Post\" com navbar + detalhe do post + footer\n *\n * onDeactivate:\n * 1. Remove a seção injetada na home page\n * 2. Remove as páginas do plugin\n */\n\nimport type { PluginRegistration } from \"../../types\";\nimport type { SiteDocument, Block, BlockType } from \"../../../schema/siteDocument\";\nimport { pluginRegistry } from \"../../pluginRegistry\";\nimport { logger } from \"../../../../utils/logger\";\n\n// ─── ID usado para a seção de blog injetada na home page ───\nconst BLOG_HOME_SECTION_ID = \"plugin-blog-home-grid\";\n\n// ─── Sample blog cards para preview ───\nconst SAMPLE_BLOG_CARDS = [\n {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n excerpt:\n \"Nossos alunos apresentaram projetos incríveis na Feira de Ciências deste ano. Confira os destaques e premiações!\",\n image:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=800&h=400&fit=crop\",\n category: \"Eventos\",\n date: \"05 Fev 2026\",\n linkHref: \"/site/p/blog/feira-de-ciencias-2026\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Matrículas Abertas para o Segundo Semestre\",\n excerpt:\n \"Garanta a vaga do seu filho na melhor escola da região. Condições especiais para matrículas antecipadas.\",\n image:\n \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2026\",\n linkHref: \"/site/p/blog/matriculas-segundo-semestre\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Preparar seu Filho para o Ano Letivo\",\n excerpt:\n \"Dicas práticas para uma transição tranquila e um início de ano produtivo para toda a família.\",\n image:\n \"https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"28 Jan 2026\",\n linkHref: \"/site/p/blog/dicas-preparar-ano-letivo\",\n linkText: \"Ler mais\",\n },\n];\n\n// ─── Conteúdo HTML rico para o post de exemplo ───\nconst SAMPLE_POST_CONTENT = `\n<h2>O que é a Feira de Ciências?</h2>\n<p>A Feira de Ciências é um evento anual que celebra a curiosidade, a pesquisa e a criatividade dos nossos alunos. Nesta edição especial de 2026, recebemos mais de <strong>500 visitantes</strong> e contamos com a participação de todas as turmas do Ensino Fundamental e Médio.</p>\n<p>Este ano, o tema central foi <em>\"Ciência e Sustentabilidade\"</em>, incentivando os estudantes a desenvolverem projetos que aliassem inovação tecnológica com responsabilidade ambiental.</p>\n\n<h2>Destaques da Edição 2026</h2>\n<p>Entre os mais de 50 projetos apresentados, alguns se destacaram pela originalidade e impacto:</p>\n<ul>\n <li><strong>Jardim Sustentável Inteligente</strong> — Alunos do 5º ano desenvolveram um sistema de irrigação automática usando sensores de umidade e placa Arduino.</li>\n <li><strong>Robótica Educacional</strong> — A turma do 8º ano criou um robô que auxilia no ensino de matemática para crianças do 1º ao 3º ano.</li>\n <li><strong>Energia Solar na Escola</strong> — Projeto do 2º ano do Ensino Médio demonstrou como painéis solares poderiam reduzir em 40% o consumo de energia da escola.</li>\n</ul>\n\n<blockquote>\n <p>\"A Feira de Ciências é um dos momentos mais importantes do nosso calendário escolar. Ver a dedicação e o brilho nos olhos dos alunos ao apresentarem seus projetos nos enche de orgulho e nos motiva a continuar investindo em educação de qualidade.\"</p>\n <p><strong>— Prof. Maria Silva, Coordenadora Pedagógica</strong></p>\n</blockquote>\n\n<h2>Premiações</h2>\n<p>O júri, composto por professores universitários e profissionais da área de tecnologia, selecionou os três melhores projetos:</p>\n<ol>\n <li><strong>1º Lugar:</strong> Jardim Sustentável Inteligente (5º ano)</li>\n <li><strong>2º Lugar:</strong> Energia Solar na Escola (2º EM)</li>\n <li><strong>3º Lugar:</strong> Robótica Educacional (8º ano)</li>\n</ol>\n\n<h2>Próximos Passos</h2>\n<p>Os três projetos finalistas representarão nossa escola na <strong>Feira Regional de Ciências</strong>, que acontecerá em março na capital. Os alunos já estão se preparando para levar suas apresentações a um público ainda maior.</p>\n<p>Parabéns a todos os participantes, professores orientadores e famílias que apoiaram essa jornada de descobertas!</p>\n`.trim();\n\n/**\n * Deep-clone um bloco com novo ID\n */\nfunction cloneBlock(block: Block, newId: string): Block {\n const cloned: Block = JSON.parse(JSON.stringify(block));\n return { ...cloned, id: newId };\n}\n\nexport const blogPlugin: PluginRegistration = {\n manifest: {\n id: \"blog\",\n version: \"1.0.0\",\n name: \"Blog\",\n description: \"Blog com posts, categorias e tags\",\n icon: \"FileText\",\n\n capabilities: {\n blocks: [\"blogPostCard\", \"blogPostGrid\", \"blogPostDetail\", \"blogCategoryFilter\", \"blogSearchBar\"],\n\n pageTemplates: [\n {\n id: \"blog-listing\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n },\n {\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n lockedStructure: true,\n nonRemovable: true,\n },\n },\n ],\n\n dataSchemas: [\n {\n type: \"blog-post\",\n label: \"Blog Post\",\n fields: [\n { name: \"title\", type: \"string\", required: true, label: \"Title\" },\n { name: \"slug\", type: \"string\", required: true, label: \"Slug\" },\n { name: \"excerpt\", type: \"string\", label: \"Excerpt\" },\n { name: \"content\", type: \"richtext\", required: true, label: \"Content\" },\n { name: \"featuredImage\", type: \"image\", label: \"Featured Image\" },\n { name: \"category\", type: \"string\", label: \"Category\" },\n { name: \"tags\", type: \"array\", label: \"Tags\" },\n { name: \"authorVariant\", type: \"string\", label: \"Author Variant\" },\n { name: \"readingTime\", type: \"number\", label: \"Reading Time\" },\n { name: \"metaTitle\", type: \"string\", label: \"Meta Title (SEO)\" },\n { name: \"metaDescription\", type: \"string\", label: \"Meta Description (SEO)\" },\n { name: \"ogImage\", type: \"image\", label: \"Open Graph Image\" },\n ],\n },\n ],\n\n contentProviders: [\"blog-posts\", \"blog-categories\"],\n },\n\n restrictions: {\n lockedFields: {\n blogPostDetail: [\"content\", \"date\"],\n },\n requiredPages: [\"blog-listing\", \"blog-post\"],\n },\n },\n\n onActivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin activating...\");\n\n const existingPageIds = new Set(document.pages.map((p) => p.id));\n const newPages = [...document.pages];\n\n // ── Encontrar home page para clonar navbar/footer ──\n const homePage =\n document.pages.find((p) => p.slug === \"home\") || document.pages[0];\n\n const homeNavbar = homePage?.structure.find((b) => b.type === \"navbar\");\n const homeFooter = homePage?.structure.find((b) => b.type === \"footer\");\n\n // ── 1. Adicionar link \"Blog\" à navbar da home page ──\n // Preserva os links existentes e apenas insere \"Blog\" antes do último item.\n if (homePage && homeNavbar) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n if (homeIdx >= 0) {\n const navbarProps = homeNavbar.props as Record<string, any>;\n const existingLinks: Array<{ text: string; href: string }> =\n Array.isArray(navbarProps.links) ? [...navbarProps.links] : [];\n const hasBlogLink = existingLinks.some(\n (l) => l.href === \"/p/blog\",\n );\n\n if (!hasBlogLink) {\n // Inserir \"Blog\" antes do último link (geralmente \"Contato\")\n const insertIdx = existingLinks.length > 0 ? existingLinks.length - 1 : 0;\n existingLinks.splice(insertIdx, 0, { text: \"Blog\", href: \"/p/blog\" });\n\n // Atualizar navbar na home page com o novo link\n const updatedStructure = newPages[homeIdx].structure.map((b) => {\n if (b.id === homeNavbar.id) {\n return { ...b, props: { ...b.props, links: existingLinks } } as Block;\n }\n return b;\n });\n newPages[homeIdx] = { ...newPages[homeIdx], structure: updatedStructure };\n logger.debug(\"Blog link added to home navbar\");\n\n // Atualizar referência para que clones nas páginas do blog usem navbar com link\n // (homeNavbar é const, então criamos a versão atualizada para uso nos clones)\n (homeNavbar as any).props = { ...navbarProps, links: existingLinks };\n }\n }\n }\n\n // ── 2. Injetar seção de blog na home page (antes do footer) ──\n if (homePage) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n const alreadyInjected = homePage.structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n\n if (homeIdx >= 0 && !alreadyInjected) {\n const blogHomeSection: Block = {\n id: BLOG_HOME_SECTION_ID,\n type: \"blogPostGrid\",\n props: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: true,\n viewAllText: \"Ver todos os posts\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block;\n\n const updatedStructure = [...newPages[homeIdx].structure];\n const footerIdx = updatedStructure.findIndex(\n (b) => b.type === \"footer\",\n );\n\n if (footerIdx >= 0) {\n updatedStructure.splice(footerIdx, 0, blogHomeSection);\n } else {\n updatedStructure.push(blogHomeSection);\n }\n\n newPages[homeIdx] = {\n ...newPages[homeIdx],\n structure: updatedStructure,\n };\n logger.debug(\"Blog section injected into home page\");\n }\n }\n\n // ── 3. Criar página \"Blog\" (listagem completa) ──\n if (!existingPageIds.has(\"blog\")) {\n const blogPageStructure: Block[] = [];\n\n // Navbar clonada da home\n if (homeNavbar) {\n blogPageStructure.push(cloneBlock(homeNavbar, \"blog-page-navbar\"));\n }\n\n // Hero banner do blog\n blogPageStructure.push({\n id: \"blog-page-hero\",\n type: \"hero\",\n props: {\n title: \"Blog\",\n subtitle: \"Novidades & Publicações\",\n description:\n \"Acompanhe as últimas novidades, eventos e conquistas da nossa comunidade escolar.\",\n variant: \"centered\",\n align: \"center\",\n overlay: true,\n overlayColor: \"rgba(79, 70, 229, 0.9)\",\n background: \"#4f46e5\",\n minHeight: \"280px\",\n },\n } as Block);\n\n // Search bar\n blogPageStructure.push({\n id: \"blog-search-bar\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Category filter\n blogPageStructure.push({\n id: \"blog-category-filter\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"chips\",\n showCount: false,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Grid de posts\n blogPageStructure.push({\n id: \"blog-grid-main\",\n type: \"blogPostGrid\",\n props: {\n title: \"\",\n subtitle: \"\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block);\n\n // Footer clonado da home\n if (homeFooter) {\n blogPageStructure.push(cloneBlock(homeFooter, \"blog-page-footer\"));\n }\n\n newPages.push({\n id: \"blog\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-listing\",\n structure: blogPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n });\n logger.debug(\"Blog listing page created\");\n }\n\n // ── 4. Criar página \"Post\" (detalhe) ──\n if (!existingPageIds.has(\"blog-post\")) {\n const postPageStructure: Block[] = [];\n\n if (homeNavbar) {\n postPageStructure.push(cloneBlock(homeNavbar, \"post-page-navbar\"));\n }\n\n postPageStructure.push({\n id: \"blog-detail-main\",\n type: \"blogPostDetail\",\n props: {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n content: SAMPLE_POST_CONTENT,\n featuredImage:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=1200&h=600&fit=crop\",\n date: \"05 Fev 2026\",\n category: \"Eventos\",\n authorVariant: \"inline\",\n readingTime: \"5 min de leitura\",\n tags: [\"Feira de Ciências\", \"Eventos\", \"Sustentabilidade\", \"Projetos\"],\n showFeaturedImage: true,\n showAuthor: true,\n showDate: true,\n showTags: true,\n showReadingTime: true,\n contentMaxWidth: \"720px\",\n },\n } as Block);\n\n if (homeFooter) {\n postPageStructure.push(cloneBlock(homeFooter, \"post-page-footer\"));\n }\n\n newPages.push({\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-post\",\n isDynamic: true,\n structure: postPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n lockedStructure: true,\n nonRemovable: true,\n },\n });\n logger.debug(\"Blog post detail page created\");\n }\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n onDeactivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin deactivating...\");\n\n const newPages = document.pages\n // Remover páginas do plugin\n .filter((page) => page.pluginId !== \"blog\")\n // Remover seção de blog injetada + link \"Blog\" da navbar\n .map((page) => {\n let structure = page.structure;\n\n // Remover seção de blog injetada\n const hasInjected = structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n if (hasInjected) {\n structure = structure.filter(\n (b) => b.id !== BLOG_HOME_SECTION_ID,\n );\n }\n\n // Remover link \"Blog\" (/p/blog) da navbar\n structure = structure.map((b) => {\n if (b.type !== \"navbar\") return b;\n const props = b.props as Record<string, any>;\n const links: Array<{ text: string; href: string }> = Array.isArray(props.links) ? props.links : [];\n const filtered = links.filter((l) => l.href !== \"/p/blog\");\n if (filtered.length !== links.length) {\n return { ...b, props: { ...props, links: filtered } } as Block;\n }\n return b;\n });\n\n if (structure !== page.structure) {\n return { ...page, structure };\n }\n return page;\n });\n\n logger.debug(\n `Removed ${document.pages.length - newPages.length} blog page(s) and injected section`,\n );\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n getEditorRestrictions(blockType: BlockType) {\n if (blockType === \"blogPostDetail\") {\n return {\n lockedFields: [\"content\", \"date\"],\n };\n }\n if (blockType === \"blogCategoryFilter\") {\n return {\n lockedFields: [\"categories\"],\n };\n }\n return undefined;\n },\n};\n\n// Auto-registrar o plugin (side effect — como os blocos fazem com componentRegistry)\npluginRegistry.register(blogPlugin);\n"],"names":["BLOG_HOME_SECTION_ID","SAMPLE_BLOG_CARDS","SAMPLE_POST_CONTENT","cloneBlock","block","newId","blogPlugin","document","logger","existingPageIds","p","newPages","homePage","homeNavbar","b","homeFooter","homeIdx","navbarProps","existingLinks","l","insertIdx","updatedStructure","alreadyInjected","blogHomeSection","footerIdx","blogPageStructure","c","postPageStructure","page","structure","props","links","filtered","blockType","pluginRegistry"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ const o = [
|
|
|
6
6
|
image: "https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=800&h=400&fit=crop",
|
|
7
7
|
category: "Novidades",
|
|
8
8
|
date: "15 Jan 2025",
|
|
9
|
-
linkHref: "/blog/bem-vindo",
|
|
9
|
+
linkHref: "/site/p/blog/bem-vindo",
|
|
10
10
|
linkText: "Ler mais"
|
|
11
11
|
},
|
|
12
12
|
{
|
|
@@ -15,7 +15,7 @@ const o = [
|
|
|
15
15
|
image: "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop",
|
|
16
16
|
category: "Educação",
|
|
17
17
|
date: "20 Jan 2025",
|
|
18
|
-
linkHref: "/blog/dicas-estudantes",
|
|
18
|
+
linkHref: "/site/p/blog/dicas-estudantes",
|
|
19
19
|
linkText: "Ler mais"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
@@ -24,7 +24,7 @@ const o = [
|
|
|
24
24
|
image: "https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=800&h=400&fit=crop",
|
|
25
25
|
category: "Institucional",
|
|
26
26
|
date: "01 Fev 2025",
|
|
27
|
-
linkHref: "/blog/novidades-semestre",
|
|
27
|
+
linkHref: "/site/p/blog/novidades-semestre",
|
|
28
28
|
linkText: "Ler mais"
|
|
29
29
|
}
|
|
30
30
|
], a = {
|
|
@@ -42,7 +42,7 @@ const o = [
|
|
|
42
42
|
variant: "default",
|
|
43
43
|
showViewAll: !1,
|
|
44
44
|
viewAllText: "Ver todos",
|
|
45
|
-
viewAllHref: "/blog"
|
|
45
|
+
viewAllHref: "/site/p/blog"
|
|
46
46
|
},
|
|
47
47
|
inspectorMeta: {
|
|
48
48
|
title: { label: "Título", inputType: "text", group: "Cabeçalho" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blogPostGrid.js","sources":["../../../../../src/engine/registry/blocks/sections/blogPostGrid.ts"],"sourcesContent":["import { BlockDefinition } from \"../../types\";\nimport { componentRegistry } from \"../../registry\";\n\n/**\n * Sample cards for editor preview.\n * In production, these are replaced by ContentProvider data.\n */\nconst sampleCards = [\n {\n title: \"Bem-vindo ao nosso blog!\",\n excerpt: \"Estamos animados em lançar nosso blog oficial. Acompanhe novidades e dicas.\",\n image: \"https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=800&h=400&fit=crop\",\n category: \"Novidades\",\n date: \"15 Jan 2025\",\n linkHref: \"/blog/bem-vindo\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Estudantes de Sucesso\",\n excerpt: \"Confira as melhores práticas para melhorar seus estudos e alcançar seus objetivos.\",\n image: \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"20 Jan 2025\",\n linkHref: \"/blog/dicas-estudantes\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Novidades para o Próximo Semestre\",\n excerpt: \"Novos cursos, eventos e melhorias que estão chegando. Saiba tudo sobre o que vem por aí.\",\n image: \"https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2025\",\n linkHref: \"/blog/novidades-semestre\",\n linkText: \"Ler mais\",\n },\n];\n\nexport const blogPostGridBlock: BlockDefinition<\"blogPostGrid\"> = {\n type: \"blogPostGrid\",\n name: \"Blog Post Grid\",\n description: \"Grid de posts do blog com suporte a dados dinâmicos (plugin Blog)\",\n category: \"sections\",\n pluginId: \"blog\",\n canHaveChildren: false,\n defaultProps: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: sampleCards,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/blog\",\n },\n inspectorMeta: {\n title: { label: \"Título\", inputType: \"text\", group: \"Cabeçalho\" },\n subtitle: { label: \"Subtítulo\", inputType: \"text\", group: \"Cabeçalho\" },\n columns: {\n label: \"Colunas\",\n inputType: \"select\",\n options: [\n { label: \"2\", value: 2 },\n { label: \"3\", value: 3 },\n { label: \"4\", value: 4 },\n ],\n group: \"Layout\",\n },\n variant: {\n label: \"Variante\",\n inputType: \"select\",\n options: [\n { label: \"Padrão\", value: \"default\" },\n { label: \"Destaque\", value: \"featured\" },\n { label: \"Minimal\", value: \"minimal\" },\n ],\n group: \"Aparência\",\n },\n showViewAll: { label: \"Mostrar 'Ver Todos'\", inputType: \"checkbox\", group: \"Rodapé\" },\n viewAllText: {\n label: \"Texto do Link\",\n inputType: \"text\",\n group: \"Rodapé\",\n showWhen: { field: \"showViewAll\", equals: true },\n },\n viewAllHref: {\n label: \"URL do Link\",\n inputType: \"text\",\n group: \"Rodapé\",\n showWhen: { field: \"showViewAll\", equals: true },\n },\n },\n};\n\n// Auto-registro\ncomponentRegistry.register(blogPostGridBlock);\n"],"names":["sampleCards","blogPostGridBlock","componentRegistry"],"mappings":";AAOA,MAAMA,IAAc;AAAA,EAClB;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAEd,GAEaC,IAAqD;AAAA,EAChE,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,cAAc;AAAA,IACZ,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAOD;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,EAAA;AAAA,EAEf,eAAe;AAAA,IACb,OAAO,EAAE,OAAO,UAAU,WAAW,QAAQ,OAAO,YAAA;AAAA,IACpD,UAAU,EAAE,OAAO,aAAa,WAAW,QAAQ,OAAO,YAAA;AAAA,IAC1D,SAAS;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,QACrB,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,QACrB,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,MAAE;AAAA,MAEzB,OAAO;AAAA,IAAA;AAAA,IAET,SAAS;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,UAAA;AAAA,QAC1B,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,QAC5B,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,MAAU;AAAA,MAEvC,OAAO;AAAA,IAAA;AAAA,IAET,aAAa,EAAE,OAAO,uBAAuB,WAAW,YAAY,OAAO,SAAA;AAAA,IAC3E,aAAa;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,EAAE,OAAO,eAAe,QAAQ,GAAA;AAAA,IAAK;AAAA,IAEjD,aAAa;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,EAAE,OAAO,eAAe,QAAQ,GAAA;AAAA,IAAK;AAAA,EACjD;AAEJ;AAGAE,EAAkB,SAASD,CAAiB;"}
|
|
1
|
+
{"version":3,"file":"blogPostGrid.js","sources":["../../../../../src/engine/registry/blocks/sections/blogPostGrid.ts"],"sourcesContent":["import { BlockDefinition } from \"../../types\";\nimport { componentRegistry } from \"../../registry\";\n\n/**\n * Sample cards for editor preview.\n * In production, these are replaced by ContentProvider data.\n */\nconst sampleCards = [\n {\n title: \"Bem-vindo ao nosso blog!\",\n excerpt: \"Estamos animados em lançar nosso blog oficial. Acompanhe novidades e dicas.\",\n image: \"https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=800&h=400&fit=crop\",\n category: \"Novidades\",\n date: \"15 Jan 2025\",\n linkHref: \"/site/p/blog/bem-vindo\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Estudantes de Sucesso\",\n excerpt: \"Confira as melhores práticas para melhorar seus estudos e alcançar seus objetivos.\",\n image: \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"20 Jan 2025\",\n linkHref: \"/site/p/blog/dicas-estudantes\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Novidades para o Próximo Semestre\",\n excerpt: \"Novos cursos, eventos e melhorias que estão chegando. Saiba tudo sobre o que vem por aí.\",\n image: \"https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2025\",\n linkHref: \"/site/p/blog/novidades-semestre\",\n linkText: \"Ler mais\",\n },\n];\n\nexport const blogPostGridBlock: BlockDefinition<\"blogPostGrid\"> = {\n type: \"blogPostGrid\",\n name: \"Blog Post Grid\",\n description: \"Grid de posts do blog com suporte a dados dinâmicos (plugin Blog)\",\n category: \"sections\",\n pluginId: \"blog\",\n canHaveChildren: false,\n defaultProps: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: sampleCards,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/site/p/blog\",\n },\n inspectorMeta: {\n title: { label: \"Título\", inputType: \"text\", group: \"Cabeçalho\" },\n subtitle: { label: \"Subtítulo\", inputType: \"text\", group: \"Cabeçalho\" },\n columns: {\n label: \"Colunas\",\n inputType: \"select\",\n options: [\n { label: \"2\", value: 2 },\n { label: \"3\", value: 3 },\n { label: \"4\", value: 4 },\n ],\n group: \"Layout\",\n },\n variant: {\n label: \"Variante\",\n inputType: \"select\",\n options: [\n { label: \"Padrão\", value: \"default\" },\n { label: \"Destaque\", value: \"featured\" },\n { label: \"Minimal\", value: \"minimal\" },\n ],\n group: \"Aparência\",\n },\n showViewAll: { label: \"Mostrar 'Ver Todos'\", inputType: \"checkbox\", group: \"Rodapé\" },\n viewAllText: {\n label: \"Texto do Link\",\n inputType: \"text\",\n group: \"Rodapé\",\n showWhen: { field: \"showViewAll\", equals: true },\n },\n viewAllHref: {\n label: \"URL do Link\",\n inputType: \"text\",\n group: \"Rodapé\",\n showWhen: { field: \"showViewAll\", equals: true },\n },\n },\n};\n\n// Auto-registro\ncomponentRegistry.register(blogPostGridBlock);\n"],"names":["sampleCards","blogPostGridBlock","componentRegistry"],"mappings":";AAOA,MAAMA,IAAc;AAAA,EAClB;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAEd,GAEaC,IAAqD;AAAA,EAChE,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,cAAc;AAAA,IACZ,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAOD;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,EAAA;AAAA,EAEf,eAAe;AAAA,IACb,OAAO,EAAE,OAAO,UAAU,WAAW,QAAQ,OAAO,YAAA;AAAA,IACpD,UAAU,EAAE,OAAO,aAAa,WAAW,QAAQ,OAAO,YAAA;AAAA,IAC1D,SAAS;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,QACrB,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,QACrB,EAAE,OAAO,KAAK,OAAO,EAAA;AAAA,MAAE;AAAA,MAEzB,OAAO;AAAA,IAAA;AAAA,IAET,SAAS;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,UAAA;AAAA,QAC1B,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,QAC5B,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,MAAU;AAAA,MAEvC,OAAO;AAAA,IAAA;AAAA,IAET,aAAa,EAAE,OAAO,uBAAuB,WAAW,YAAY,OAAO,SAAA;AAAA,IAC3E,aAAa;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,EAAE,OAAO,eAAe,QAAQ,GAAA;AAAA,IAAK;AAAA,IAEjD,aAAa;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,EAAE,OAAO,eAAe,QAAQ,GAAA;AAAA,IAAK;AAAA,EACjD;AAEJ;AAGAE,EAAkB,SAASD,CAAiB;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNavbarAutoSync.d.ts","sourceRoot":"","sources":["../../src/hooks/useNavbarAutoSync.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useNavbarAutoSync.d.ts","sourceRoot":"","sources":["../../src/hooks/useNavbarAutoSync.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAU7D;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,QA6D1D"}
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import { useRef as
|
|
2
|
-
import { syncNavbarLinks as
|
|
3
|
-
function
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
if (!
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { useRef as d, useEffect as v } from "react";
|
|
2
|
+
import { syncNavbarLinks as I } from "../utils/navbarSync.js";
|
|
3
|
+
function b(n, i) {
|
|
4
|
+
const r = d([]), u = d(!1);
|
|
5
|
+
v(() => {
|
|
6
|
+
if (!n) return;
|
|
7
|
+
const s = n.pages.map((e) => ({
|
|
8
|
+
id: e.id,
|
|
9
|
+
name: e.name,
|
|
10
|
+
slug: e.slug,
|
|
11
|
+
pluginId: e.pluginId
|
|
12
|
+
})), a = r.current;
|
|
13
|
+
if (!u.current) {
|
|
14
|
+
u.current = !0, r.current = s;
|
|
15
|
+
return;
|
|
13
16
|
}
|
|
14
|
-
e.
|
|
15
|
-
|
|
17
|
+
const g = new Set(a.map((e) => e.id)), l = new Set(s.map((e) => e.id)), o = s.filter((e) => !g.has(e.id)), c = a.filter((e) => !l.has(e.id)), f = o.some((e) => e.pluginId) || c.some((e) => e.pluginId), m = s.some((e) => {
|
|
18
|
+
if (e.pluginId) return !1;
|
|
19
|
+
const t = a.find((P) => P.id === e.id);
|
|
20
|
+
return t && (t.name !== e.name || t.slug !== e.slug);
|
|
21
|
+
}), h = o.some((e) => !e.pluginId), p = c.some((e) => !e.pluginId);
|
|
22
|
+
if (!f && (m || h || p)) {
|
|
23
|
+
const e = I(n);
|
|
24
|
+
e.length > 0 && i(e, "Auto-sync navbar links");
|
|
25
|
+
}
|
|
26
|
+
r.current = s;
|
|
27
|
+
}, [n, i]);
|
|
16
28
|
}
|
|
17
29
|
export {
|
|
18
|
-
|
|
30
|
+
b as useNavbarAutoSync
|
|
19
31
|
};
|
|
20
32
|
//# sourceMappingURL=useNavbarAutoSync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNavbarAutoSync.js","sources":["../../src/hooks/useNavbarAutoSync.ts"],"sourcesContent":["/**\n * useNavbarAutoSync Hook\n * Hook para sincronização automática de links do navbar\n * Detecta mudanças nas páginas e atualiza navbar automaticamente\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { SiteDocument } from \"../engine/schema/siteDocument\";\nimport { syncNavbarLinks } from \"../utils/navbarSync\";\n\n/**\n * Hook para sincronização automática de links do navbar\n * Detecta mudanças nas páginas e atualiza navbar automaticamente\n */\nexport function useNavbarAutoSync(\n document: SiteDocument | null,\n applyChange: (patch: any[], description?: string) => void\n) {\n const previousPagesRef = useRef<
|
|
1
|
+
{"version":3,"file":"useNavbarAutoSync.js","sources":["../../src/hooks/useNavbarAutoSync.ts"],"sourcesContent":["/**\n * useNavbarAutoSync Hook\n * Hook para sincronização automática de links do navbar\n * Detecta mudanças nas páginas e atualiza navbar automaticamente.\n *\n * Skips sync when plugin pages are added/removed — plugin onActivate/onDeactivate\n * already handles navbar links and auto-sync would destroy custom links.\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { SiteDocument } from \"../engine/schema/siteDocument\";\nimport { syncNavbarLinks } from \"../utils/navbarSync\";\n\ninterface PageSnapshot {\n id: string;\n name: string;\n slug: string;\n pluginId?: string;\n}\n\n/**\n * Hook para sincronização automática de links do navbar\n * Detecta mudanças nas páginas e atualiza navbar automaticamente\n */\nexport function useNavbarAutoSync(\n document: SiteDocument | null,\n applyChange: (patch: any[], description?: string) => void\n) {\n const previousPagesRef = useRef<PageSnapshot[]>([]);\n const initializedRef = useRef(false);\n\n useEffect(() => {\n if (!document) return;\n\n const currentPages: PageSnapshot[] = document.pages.map((p) => ({\n id: p.id,\n name: p.name,\n slug: p.slug,\n pluginId: p.pluginId,\n }));\n\n const prevPages = previousPagesRef.current;\n\n // Skip first render (no previous state to compare)\n if (!initializedRef.current) {\n initializedRef.current = true;\n previousPagesRef.current = currentPages;\n return;\n }\n\n // Detect what changed\n const prevIds = new Set(prevPages.map((p) => p.id));\n const currIds = new Set(currentPages.map((p) => p.id));\n\n const addedPages = currentPages.filter((p) => !prevIds.has(p.id));\n const removedPages = prevPages.filter((p) => !currIds.has(p.id));\n\n const hasPluginPagesChanged =\n addedPages.some((p) => p.pluginId) ||\n removedPages.some((p) => p.pluginId);\n\n // Check if non-plugin pages were renamed or re-slugged\n const hasRegularPageChanges = currentPages.some((p) => {\n if (p.pluginId) return false;\n const prev = prevPages.find((pp) => pp.id === p.id);\n return prev && (prev.name !== p.name || prev.slug !== p.slug);\n });\n\n // Check if non-plugin pages were added or removed\n const hasRegularPageAdded = addedPages.some((p) => !p.pluginId);\n const hasRegularPageRemoved = removedPages.some((p) => !p.pluginId);\n\n // Only sync if changes are from regular pages (not plugins)\n // Plugin onActivate/onDeactivate manages its own navbar links\n const shouldSync =\n !hasPluginPagesChanged &&\n (hasRegularPageChanges || hasRegularPageAdded || hasRegularPageRemoved);\n\n if (shouldSync) {\n const patches = syncNavbarLinks(document);\n if (patches.length > 0) {\n applyChange(patches, \"Auto-sync navbar links\");\n }\n }\n\n previousPagesRef.current = currentPages;\n }, [document, applyChange]);\n}\n"],"names":["useNavbarAutoSync","document","applyChange","previousPagesRef","useRef","initializedRef","useEffect","currentPages","p","prevPages","prevIds","currIds","addedPages","removedPages","hasPluginPagesChanged","hasRegularPageChanges","prev","pp","hasRegularPageAdded","hasRegularPageRemoved","patches","syncNavbarLinks"],"mappings":";;AAwBO,SAASA,EACdC,GACAC,GACA;AACA,QAAMC,IAAmBC,EAAuB,EAAE,GAC5CC,IAAiBD,EAAO,EAAK;AAEnC,EAAAE,EAAU,MAAM;AACd,QAAI,CAACL,EAAU;AAEf,UAAMM,IAA+BN,EAAS,MAAM,IAAI,CAACO,OAAO;AAAA,MAC9D,IAAIA,EAAE;AAAA,MACN,MAAMA,EAAE;AAAA,MACR,MAAMA,EAAE;AAAA,MACR,UAAUA,EAAE;AAAA,IAAA,EACZ,GAEIC,IAAYN,EAAiB;AAGnC,QAAI,CAACE,EAAe,SAAS;AAC3B,MAAAA,EAAe,UAAU,IACzBF,EAAiB,UAAUI;AAC3B;AAAA,IACF;AAGA,UAAMG,IAAU,IAAI,IAAID,EAAU,IAAI,CAACD,MAAMA,EAAE,EAAE,CAAC,GAC5CG,IAAU,IAAI,IAAIJ,EAAa,IAAI,CAACC,MAAMA,EAAE,EAAE,CAAC,GAE/CI,IAAaL,EAAa,OAAO,CAACC,MAAM,CAACE,EAAQ,IAAIF,EAAE,EAAE,CAAC,GAC1DK,IAAeJ,EAAU,OAAO,CAACD,MAAM,CAACG,EAAQ,IAAIH,EAAE,EAAE,CAAC,GAEzDM,IACJF,EAAW,KAAK,CAACJ,MAAMA,EAAE,QAAQ,KACjCK,EAAa,KAAK,CAACL,MAAMA,EAAE,QAAQ,GAG/BO,IAAwBR,EAAa,KAAK,CAACC,MAAM;AACrD,UAAIA,EAAE,SAAU,QAAO;AACvB,YAAMQ,IAAOP,EAAU,KAAK,CAACQ,MAAOA,EAAG,OAAOT,EAAE,EAAE;AAClD,aAAOQ,MAASA,EAAK,SAASR,EAAE,QAAQQ,EAAK,SAASR,EAAE;AAAA,IAC1D,CAAC,GAGKU,IAAsBN,EAAW,KAAK,CAACJ,MAAM,CAACA,EAAE,QAAQ,GACxDW,IAAwBN,EAAa,KAAK,CAACL,MAAM,CAACA,EAAE,QAAQ;AAQlE,QAHE,CAACM,MACAC,KAAyBG,KAAuBC,IAEnC;AACd,YAAMC,IAAUC,EAAgBpB,CAAQ;AACxC,MAAImB,EAAQ,SAAS,KACnBlB,EAAYkB,GAAS,wBAAwB;AAAA,IAEjD;AAEA,IAAAjB,EAAiB,UAAUI;AAAA,EAC7B,GAAG,CAACN,GAAUC,CAAW,CAAC;AAC5B;"}
|
|
@@ -20,7 +20,9 @@ interface NavbarLink {
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function findNavbarBlocks(document: SiteDocument): NavbarBlockInfo[];
|
|
22
22
|
/**
|
|
23
|
-
* Gera array de links do navbar a partir das páginas do documento
|
|
23
|
+
* Gera array de links do navbar a partir das páginas do documento.
|
|
24
|
+
* Filtra páginas dinâmicas (isDynamic: true) como "blog/:slug"
|
|
25
|
+
* que não devem aparecer como links de navegação.
|
|
24
26
|
*/
|
|
25
27
|
export declare function generateNavbarLinks(pages: SitePage[]): NavbarLink[];
|
|
26
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbarSync.d.ts","sourceRoot":"","sources":["../../src/utils/navbarSync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAS,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAI7C;;GAEG;AACH,UAAU,eAAe;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAkDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,eAAe,EAAE,CAQ1E;AAED
|
|
1
|
+
{"version":3,"file":"navbarSync.d.ts","sourceRoot":"","sources":["../../src/utils/navbarSync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAS,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAI7C;;GAEG;AACH,UAAU,eAAe;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAkDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,eAAe,EAAE,CAQ1E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,CAOnE;AAeD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,KAAK,CAoC7D"}
|
package/dist/utils/navbarSync.js
CHANGED
|
@@ -19,7 +19,7 @@ function f(t) {
|
|
|
19
19
|
return o;
|
|
20
20
|
}
|
|
21
21
|
function l(t) {
|
|
22
|
-
return t.map((o) => ({
|
|
22
|
+
return t.filter((o) => !o.isDynamic).map((o) => ({
|
|
23
23
|
text: o.name,
|
|
24
24
|
href: o.slug === "home" ? "/" : `/p/${o.slug}`
|
|
25
25
|
}));
|
|
@@ -27,7 +27,7 @@ function l(t) {
|
|
|
27
27
|
function u(t) {
|
|
28
28
|
return t.props._autoSync !== !1;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function d(t) {
|
|
31
31
|
const o = [], n = l(t.pages), c = f(t);
|
|
32
32
|
for (const r of c)
|
|
33
33
|
if (u(r.block))
|
|
@@ -51,6 +51,6 @@ function h(t) {
|
|
|
51
51
|
export {
|
|
52
52
|
f as findNavbarBlocks,
|
|
53
53
|
l as generateNavbarLinks,
|
|
54
|
-
|
|
54
|
+
d as syncNavbarLinks
|
|
55
55
|
};
|
|
56
56
|
//# sourceMappingURL=navbarSync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbarSync.js","sources":["../../src/utils/navbarSync.ts"],"sourcesContent":["/**\n * Navbar Sync - Sincronização automática de links do navbar\n * Sistema que mantém os links do navbar atualizados com as páginas do documento\n */\n\nimport { Block, NavbarBlock, SiteDocument, SitePage } from \"@/engine/schema/siteDocument\";\nimport { Patch } from \"@/engine/patch/types\";\nimport { PatchBuilder } from \"@/engine/patch/PatchBuilder\";\nimport { logger } from \"./logger\";\n\n/**\n * Informação sobre um bloco navbar encontrado\n */\ninterface NavbarBlockInfo {\n block: NavbarBlock;\n pageId: string;\n blockId: string;\n}\n\n/**\n * Link do navbar\n */\ninterface NavbarLink {\n text: string;\n href: string;\n}\n\n/**\n * Busca recursiva por blocos navbar na estrutura\n */\nfunction findNavbarBlocksInStructure(\n structure: Block[],\n pageId: string,\n navbars: NavbarBlockInfo[] = []\n): NavbarBlockInfo[] {\n for (const block of structure) {\n // Se é um navbar, adiciona à lista\n if (block.type === \"navbar\") {\n navbars.push({\n block: block as NavbarBlock,\n pageId,\n blockId: block.id,\n });\n }\n\n // Busca recursiva em children\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) {\n findNavbarBlocksInStructure(props.children, pageId, navbars);\n }\n\n // Busca em slots de card\n if (block.type === \"card\") {\n if (props?.header && Array.isArray(props.header)) {\n findNavbarBlocksInStructure(props.header, pageId, navbars);\n }\n if (props?.content && Array.isArray(props.content)) {\n findNavbarBlocksInStructure(props.content, pageId, navbars);\n }\n if (props?.footer && Array.isArray(props.footer)) {\n findNavbarBlocksInStructure(props.footer, pageId, navbars);\n }\n }\n\n // Busca em children de section/container/box/stack/grid\n if ([\"section\", \"container\", \"box\", \"stack\", \"grid\"].includes(block.type)) {\n if (props?.children && Array.isArray(props.children)) {\n findNavbarBlocksInStructure(props.children, pageId, navbars);\n }\n }\n }\n\n return navbars;\n}\n\n/**\n * Encontra todos os blocos navbar em todas as páginas do documento\n */\nexport function findNavbarBlocks(document: SiteDocument): NavbarBlockInfo[] {\n const navbars: NavbarBlockInfo[] = [];\n\n for (const page of document.pages) {\n findNavbarBlocksInStructure(page.structure, page.id, navbars);\n }\n\n return navbars;\n}\n\n/**\n * Gera array de links do navbar a partir das páginas do documento\n */\nexport function generateNavbarLinks(pages: SitePage[]): NavbarLink[] {\n return pages.map((page) => ({\n
|
|
1
|
+
{"version":3,"file":"navbarSync.js","sources":["../../src/utils/navbarSync.ts"],"sourcesContent":["/**\n * Navbar Sync - Sincronização automática de links do navbar\n * Sistema que mantém os links do navbar atualizados com as páginas do documento\n */\n\nimport { Block, NavbarBlock, SiteDocument, SitePage } from \"@/engine/schema/siteDocument\";\nimport { Patch } from \"@/engine/patch/types\";\nimport { PatchBuilder } from \"@/engine/patch/PatchBuilder\";\nimport { logger } from \"./logger\";\n\n/**\n * Informação sobre um bloco navbar encontrado\n */\ninterface NavbarBlockInfo {\n block: NavbarBlock;\n pageId: string;\n blockId: string;\n}\n\n/**\n * Link do navbar\n */\ninterface NavbarLink {\n text: string;\n href: string;\n}\n\n/**\n * Busca recursiva por blocos navbar na estrutura\n */\nfunction findNavbarBlocksInStructure(\n structure: Block[],\n pageId: string,\n navbars: NavbarBlockInfo[] = []\n): NavbarBlockInfo[] {\n for (const block of structure) {\n // Se é um navbar, adiciona à lista\n if (block.type === \"navbar\") {\n navbars.push({\n block: block as NavbarBlock,\n pageId,\n blockId: block.id,\n });\n }\n\n // Busca recursiva em children\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) {\n findNavbarBlocksInStructure(props.children, pageId, navbars);\n }\n\n // Busca em slots de card\n if (block.type === \"card\") {\n if (props?.header && Array.isArray(props.header)) {\n findNavbarBlocksInStructure(props.header, pageId, navbars);\n }\n if (props?.content && Array.isArray(props.content)) {\n findNavbarBlocksInStructure(props.content, pageId, navbars);\n }\n if (props?.footer && Array.isArray(props.footer)) {\n findNavbarBlocksInStructure(props.footer, pageId, navbars);\n }\n }\n\n // Busca em children de section/container/box/stack/grid\n if ([\"section\", \"container\", \"box\", \"stack\", \"grid\"].includes(block.type)) {\n if (props?.children && Array.isArray(props.children)) {\n findNavbarBlocksInStructure(props.children, pageId, navbars);\n }\n }\n }\n\n return navbars;\n}\n\n/**\n * Encontra todos os blocos navbar em todas as páginas do documento\n */\nexport function findNavbarBlocks(document: SiteDocument): NavbarBlockInfo[] {\n const navbars: NavbarBlockInfo[] = [];\n\n for (const page of document.pages) {\n findNavbarBlocksInStructure(page.structure, page.id, navbars);\n }\n\n return navbars;\n}\n\n/**\n * Gera array de links do navbar a partir das páginas do documento.\n * Filtra páginas dinâmicas (isDynamic: true) como \"blog/:slug\"\n * que não devem aparecer como links de navegação.\n */\nexport function generateNavbarLinks(pages: SitePage[]): NavbarLink[] {\n return pages\n .filter((page) => !page.isDynamic)\n .map((page) => ({\n text: page.name,\n href: page.slug === \"home\" ? \"/\" : `/p/${page.slug}`,\n }));\n}\n\n/**\n * Verifica se um bloco navbar deve ter sincronização automática\n */\nfunction shouldAutoSync(navbarBlock: NavbarBlock): boolean {\n const props = navbarBlock.props as Record<string, any>;\n // Se _autoSync foi explicitamente setado como false, respeitar\n if (props._autoSync === false) {\n return false;\n }\n // Por padrão, sincronizar (undefined ou true)\n return true;\n}\n\n/**\n * Sincroniza os links de todos os navbars com as páginas do documento\n * Retorna array de patches para aplicar\n */\nexport function syncNavbarLinks(document: SiteDocument): Patch {\n const patches: Patch = [];\n\n // Gera links a partir das páginas\n const links = generateNavbarLinks(document.pages);\n\n // Encontra todos os navbars\n const navbars = findNavbarBlocks(document);\n\n // Para cada navbar, cria patch de atualização\n for (const navbarInfo of navbars) {\n // Verifica se deve sincronizar\n if (!shouldAutoSync(navbarInfo.block)) {\n continue;\n }\n\n try {\n // Cria patch para atualizar a propriedade links\n const patch = PatchBuilder.updateBlockProp(\n document,\n navbarInfo.pageId,\n navbarInfo.blockId,\n \"links\",\n links\n );\n\n patches.push(...patch);\n } catch (error) {\n logger.warn(\n `Failed to sync navbar ${navbarInfo.blockId} in page ${navbarInfo.pageId}:`,\n error\n );\n }\n }\n\n return patches;\n}\n"],"names":["findNavbarBlocksInStructure","structure","pageId","navbars","block","props","findNavbarBlocks","document","page","generateNavbarLinks","pages","shouldAutoSync","navbarBlock","syncNavbarLinks","patches","links","navbarInfo","patch","PatchBuilder","error","logger"],"mappings":";;AA8BA,SAASA,EACPC,GACAC,GACAC,IAA6B,CAAA,GACV;AACnB,aAAWC,KAASH,GAAW;AAE7B,IAAIG,EAAM,SAAS,YACjBD,EAAQ,KAAK;AAAA,MACX,OAAAC;AAAA,MACA,QAAAF;AAAA,MACA,SAASE,EAAM;AAAA,IAAA,CAChB;AAIH,UAAMC,IAAQD,EAAM;AACpB,IAAIC,GAAO,YAAY,MAAM,QAAQA,EAAM,QAAQ,KACjDL,EAA4BK,EAAM,UAAUH,GAAQC,CAAO,GAIzDC,EAAM,SAAS,WACbC,GAAO,UAAU,MAAM,QAAQA,EAAM,MAAM,KAC7CL,EAA4BK,EAAM,QAAQH,GAAQC,CAAO,GAEvDE,GAAO,WAAW,MAAM,QAAQA,EAAM,OAAO,KAC/CL,EAA4BK,EAAM,SAASH,GAAQC,CAAO,GAExDE,GAAO,UAAU,MAAM,QAAQA,EAAM,MAAM,KAC7CL,EAA4BK,EAAM,QAAQH,GAAQC,CAAO,IAKzD,CAAC,WAAW,aAAa,OAAO,SAAS,MAAM,EAAE,SAASC,EAAM,IAAI,KAClEC,GAAO,YAAY,MAAM,QAAQA,EAAM,QAAQ,KACjDL,EAA4BK,EAAM,UAAUH,GAAQC,CAAO;AAAA,EAGjE;AAEA,SAAOA;AACT;AAKO,SAASG,EAAiBC,GAA2C;AAC1E,QAAMJ,IAA6B,CAAA;AAEnC,aAAWK,KAAQD,EAAS;AAC1B,IAAAP,EAA4BQ,EAAK,WAAWA,EAAK,IAAIL,CAAO;AAG9D,SAAOA;AACT;AAOO,SAASM,EAAoBC,GAAiC;AACnE,SAAOA,EACJ,OAAO,CAACF,MAAS,CAACA,EAAK,SAAS,EAChC,IAAI,CAACA,OAAU;AAAA,IACd,MAAMA,EAAK;AAAA,IACX,MAAMA,EAAK,SAAS,SAAS,MAAM,MAAMA,EAAK,IAAI;AAAA,EAAA,EAClD;AACN;AAKA,SAASG,EAAeC,GAAmC;AAGzD,SAFcA,EAAY,MAEhB,cAAc;AAK1B;AAMO,SAASC,EAAgBN,GAA+B;AAC7D,QAAMO,IAAiB,CAAA,GAGjBC,IAAQN,EAAoBF,EAAS,KAAK,GAG1CJ,IAAUG,EAAiBC,CAAQ;AAGzC,aAAWS,KAAcb;AAEvB,QAAKQ,EAAeK,EAAW,KAAK;AAIpC,UAAI;AAEF,cAAMC,IAAQC,EAAa;AAAA,UACzBX;AAAA,UACAS,EAAW;AAAA,UACXA,EAAW;AAAA,UACX;AAAA,UACAD;AAAA,QAAA;AAGF,QAAAD,EAAQ,KAAK,GAAGG,CAAK;AAAA,MACvB,SAASE,GAAO;AACd,QAAAC,EAAO;AAAA,UACL,yBAAyBJ,EAAW,OAAO,YAAYA,EAAW,MAAM;AAAA,UACxEG;AAAA,QAAA;AAAA,MAEJ;AAGF,SAAOL;AACT;"}
|