gatsby-attainlabs-cms 1.0.27 → 1.0.29
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/sliceWrapper.js +71 -1
- package/gatsby-node.js +76 -32
- package/package.json +1 -1
- package/src/sliceWrapper.tsx +71 -0
package/dist/sliceWrapper.js
CHANGED
|
@@ -12,7 +12,14 @@ export default function SliceWrapper({ sliceContext, data, }) {
|
|
|
12
12
|
console.warn(`Component "${pathFormatted}" not found in CMS_COMPONENTS`);
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
|
-
return (_jsx(Component, { ...props, trustPilotData: data.allTrustPilotReviews.edges[0].node
|
|
15
|
+
return (_jsx(Component, { ...props, trustPilotData: data.allTrustPilotReviews.edges[0].node, blogs: {
|
|
16
|
+
sliderBlogs: {
|
|
17
|
+
...data.sliderBlogs,
|
|
18
|
+
},
|
|
19
|
+
allBlogs: {
|
|
20
|
+
...data.allBlogs,
|
|
21
|
+
},
|
|
22
|
+
} }));
|
|
16
23
|
}
|
|
17
24
|
export const TrustPilotQuery = graphql `
|
|
18
25
|
query {
|
|
@@ -47,5 +54,68 @@ export const TrustPilotQuery = graphql `
|
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
}
|
|
57
|
+
allBlogs: allBlogs {
|
|
58
|
+
edges {
|
|
59
|
+
node {
|
|
60
|
+
blocks {
|
|
61
|
+
content {
|
|
62
|
+
props {
|
|
63
|
+
content {
|
|
64
|
+
props {
|
|
65
|
+
text
|
|
66
|
+
image {
|
|
67
|
+
desktop {
|
|
68
|
+
url
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
# type
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
root {
|
|
77
|
+
props {
|
|
78
|
+
author
|
|
79
|
+
datePublished
|
|
80
|
+
pageUrl
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
sliderBlogs: allBlogs(
|
|
88
|
+
limit: 9
|
|
89
|
+
sort: { blocks: { root: { props: { datePublished: DESC } } } }
|
|
90
|
+
) {
|
|
91
|
+
edges {
|
|
92
|
+
node {
|
|
93
|
+
blocks {
|
|
94
|
+
content {
|
|
95
|
+
props {
|
|
96
|
+
content {
|
|
97
|
+
props {
|
|
98
|
+
text
|
|
99
|
+
image {
|
|
100
|
+
desktop {
|
|
101
|
+
url
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
# type
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
root {
|
|
110
|
+
props {
|
|
111
|
+
author
|
|
112
|
+
datePublished
|
|
113
|
+
pageUrl
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
50
120
|
}
|
|
51
121
|
`;
|
package/gatsby-node.js
CHANGED
|
@@ -12,7 +12,7 @@ const brands = {
|
|
|
12
12
|
"Attain Finance": "attainfinance",
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
const generatePage = async (blocks, layout) => {
|
|
15
|
+
const generatePage = async (blocks, layout, isNested) => {
|
|
16
16
|
// Validate input parameters
|
|
17
17
|
if (!Array.isArray(blocks)) {
|
|
18
18
|
throw new Error("Invalid parameters passed to createPage.");
|
|
@@ -27,22 +27,21 @@ const generatePage = async (blocks, layout) => {
|
|
|
27
27
|
const pageContent = `
|
|
28
28
|
/* This is a generated file by the gatsby-attainlabs-cms plugin. Any changes will be overwritten on the next build. */
|
|
29
29
|
import { Slice } from "gatsby";
|
|
30
|
-
import SEO from "../components/SEO";
|
|
31
|
-
import Layout from "../layouts/${layout}";
|
|
30
|
+
import SEO from "../${isNested && "../"}components/SEO";
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
export const Head = ({ pageContext }: any) => {
|
|
36
35
|
const blocks = pageContext.blocks || { root: { props: { meta: {} } } };
|
|
37
36
|
const { title, description } = blocks.root.props.meta;
|
|
38
|
-
return <SEO title={title} description={description} noIndex={true} />;
|
|
37
|
+
return <SEO title={title || ""} description={description || ""} noIndex={true} />;
|
|
39
38
|
};
|
|
40
39
|
|
|
41
40
|
const Page = ({pageContext}:any ) => {
|
|
42
41
|
return (
|
|
43
|
-
|
|
42
|
+
<div sx={{bg:"white"}}>
|
|
44
43
|
${generateSlices(blocks)}
|
|
45
|
-
|
|
44
|
+
</div>
|
|
46
45
|
);
|
|
47
46
|
};
|
|
48
47
|
|
|
@@ -301,6 +300,7 @@ exports.sourceNodes = async (
|
|
|
301
300
|
);
|
|
302
301
|
return; // stop execution early
|
|
303
302
|
}
|
|
303
|
+
|
|
304
304
|
if (!brand || !businessUnitId) {
|
|
305
305
|
console.warn(
|
|
306
306
|
"⚠️ [gatsby-attainlabs-cms] Invalid or missing 'brand' option for Trustpilot integration. " +
|
|
@@ -310,6 +310,10 @@ exports.sourceNodes = async (
|
|
|
310
310
|
return; // stop execution early
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
console.log(
|
|
314
|
+
`ℹ️ [gatsby-attainlabs-cms] Fetching Firebase Blogs Data brand: ${brand}`
|
|
315
|
+
);
|
|
316
|
+
|
|
313
317
|
const fetchTrustpilotData = async (endpoint) => {
|
|
314
318
|
try {
|
|
315
319
|
const response = await fetch(
|
|
@@ -344,7 +348,7 @@ exports.sourceNodes = async (
|
|
|
344
348
|
recentReviews: recentReviewsData || {},
|
|
345
349
|
};
|
|
346
350
|
|
|
347
|
-
|
|
351
|
+
createNode({
|
|
348
352
|
...combinedData,
|
|
349
353
|
id: createNodeId("trustPilotReviews"),
|
|
350
354
|
parent: null,
|
|
@@ -356,16 +360,31 @@ exports.sourceNodes = async (
|
|
|
356
360
|
}
|
|
357
361
|
|
|
358
362
|
// Blogs node creation
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
363
|
+
|
|
364
|
+
const fetchBlogData = async () => {
|
|
365
|
+
try {
|
|
366
|
+
const response = await fetch(
|
|
367
|
+
`https://attain-finance-cms-default-rtdb.firebaseio.com/cms/brands/${brands[brand]}/pages.json`
|
|
368
|
+
);
|
|
369
|
+
if (!response.ok) {
|
|
370
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return await response.json();
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.error(`Failed to fetch data from Firebase`, error.message);
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const firebaseData = await fetchBlogData();
|
|
362
381
|
|
|
363
382
|
const allBlogs = [];
|
|
364
383
|
|
|
365
384
|
for (const [key, value] of Object.entries(firebaseData)) {
|
|
366
385
|
const category =
|
|
367
|
-
value?.draft?.blocks?.root?.props?.category
|
|
368
|
-
value?.blocks?.root?.props?.category
|
|
386
|
+
value?.draft?.blocks?.root?.props?.category ||
|
|
387
|
+
value?.blocks?.root?.props?.category;
|
|
369
388
|
|
|
370
389
|
if (category === "blog") {
|
|
371
390
|
allBlogs.push(value);
|
|
@@ -374,8 +393,8 @@ exports.sourceNodes = async (
|
|
|
374
393
|
if (value.hasOwnProperty("children")) {
|
|
375
394
|
for (const [childKey, childValue] of Object.entries(value["children"])) {
|
|
376
395
|
const childCategory =
|
|
377
|
-
childValue?.draft?.blocks?.root?.props?.category
|
|
378
|
-
childValue?.blocks?.root?.props?.category
|
|
396
|
+
childValue?.draft?.blocks?.root?.props?.category ||
|
|
397
|
+
childValue?.blocks?.root?.props?.category;
|
|
379
398
|
|
|
380
399
|
if (childCategory === "blog") {
|
|
381
400
|
allBlogs.push(childValue);
|
|
@@ -424,8 +443,32 @@ exports.createPages = async ({ actions, store }, pluginOptions) => {
|
|
|
424
443
|
const firebaseData = await fetch(
|
|
425
444
|
`https://attain-finance-cms-default-rtdb.firebaseio.com/cms/brands/${brands[brand]}/pages.json`
|
|
426
445
|
);
|
|
446
|
+
|
|
427
447
|
const firebaseJson = await firebaseData.json();
|
|
428
|
-
|
|
448
|
+
|
|
449
|
+
async function processPage(page, parentPath = "") {
|
|
450
|
+
// Check for folderUrl first — handle nested folders immediately
|
|
451
|
+
if (
|
|
452
|
+
page.folderUrl &&
|
|
453
|
+
page.children &&
|
|
454
|
+
Object.keys(page.children).length > 0
|
|
455
|
+
) {
|
|
456
|
+
// use folderUrl instead of pageUrl for folder structure
|
|
457
|
+
const folderPath = parentPath
|
|
458
|
+
? path.join(parentPath, page.folderUrl)
|
|
459
|
+
: page.folderUrl;
|
|
460
|
+
const folderFullPath = path.join(siteRoot, "src/cms/pages", folderPath);
|
|
461
|
+
|
|
462
|
+
await fse.ensureDir(folderFullPath);
|
|
463
|
+
|
|
464
|
+
for (const child of Object.values(page.children)) {
|
|
465
|
+
await processPage(child, folderPath);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return; // Stop here for folders — no page created for folder node
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// 🧩 Step 2: Process actual pages (no folderUrl)
|
|
429
472
|
if (page.template === "visual-editor" && page.published) {
|
|
430
473
|
const {
|
|
431
474
|
blocks: {
|
|
@@ -437,13 +480,12 @@ exports.createPages = async ({ actions, store }, pluginOptions) => {
|
|
|
437
480
|
id,
|
|
438
481
|
} = page;
|
|
439
482
|
|
|
440
|
-
//
|
|
483
|
+
// Create slice for each block
|
|
441
484
|
await Promise.all(
|
|
442
485
|
content.map(async (b) => {
|
|
443
486
|
const name = b.props.component.name;
|
|
444
487
|
const sliceId = `block--${pageUrl}--${name}--${id}--${crypto.randomUUID()}`;
|
|
445
|
-
|
|
446
|
-
// here we could await something per slice if needed later
|
|
488
|
+
|
|
447
489
|
createSlice({
|
|
448
490
|
id: sliceId,
|
|
449
491
|
component: path.resolve(
|
|
@@ -455,28 +497,30 @@ exports.createPages = async ({ actions, store }, pluginOptions) => {
|
|
|
455
497
|
...b.props,
|
|
456
498
|
},
|
|
457
499
|
});
|
|
458
|
-
|
|
500
|
+
|
|
501
|
+
b["sliceId"] = sliceId;
|
|
459
502
|
return b;
|
|
460
503
|
})
|
|
461
504
|
);
|
|
462
505
|
|
|
463
|
-
|
|
464
|
-
const
|
|
506
|
+
// Generate page file
|
|
507
|
+
const pageSource = await generatePage(content, layout, parentPath);
|
|
508
|
+
const folderPath = parentPath ? path.join(parentPath, pageUrl) : pageUrl;
|
|
509
|
+
const outPath = path.join(siteRoot, "src/cms/pages", `${folderPath}.tsx`);
|
|
465
510
|
|
|
466
511
|
await fse.outputFile(outPath, pageSource);
|
|
512
|
+
|
|
467
513
|
await createPage({
|
|
468
|
-
path:
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
},
|
|
514
|
+
path: folderPath.endsWith("/index")
|
|
515
|
+
? `/${parentPath}`
|
|
516
|
+
: `/${folderPath}`,
|
|
517
|
+
component: outPath,
|
|
518
|
+
context: { ...page },
|
|
473
519
|
});
|
|
474
|
-
|
|
475
|
-
// const pageSource = await generatePage(content, pageUrl);
|
|
476
|
-
// const outPath = path.join(siteRoot, "src/pages", `${pageUrl}.tsx`);
|
|
477
|
-
// // Generate the page itself
|
|
478
|
-
// await fse.outputFile(outPath, pageSource);
|
|
479
|
-
// console.log(`✅ Wrote page to ${outPath}`);
|
|
480
520
|
}
|
|
481
521
|
}
|
|
522
|
+
|
|
523
|
+
for (const page of Object.values(firebaseJson)) {
|
|
524
|
+
await processPage(page);
|
|
525
|
+
}
|
|
482
526
|
};
|
package/package.json
CHANGED
package/src/sliceWrapper.tsx
CHANGED
|
@@ -31,6 +31,14 @@ export default function SliceWrapper({
|
|
|
31
31
|
<Component
|
|
32
32
|
{...props}
|
|
33
33
|
trustPilotData={data.allTrustPilotReviews.edges[0].node}
|
|
34
|
+
blogs={{
|
|
35
|
+
sliderBlogs: {
|
|
36
|
+
...data.sliderBlogs,
|
|
37
|
+
},
|
|
38
|
+
allBlogs: {
|
|
39
|
+
...data.allBlogs,
|
|
40
|
+
},
|
|
41
|
+
}}
|
|
34
42
|
/>
|
|
35
43
|
);
|
|
36
44
|
}
|
|
@@ -68,5 +76,68 @@ export const TrustPilotQuery = graphql`
|
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
}
|
|
79
|
+
allBlogs: allBlogs {
|
|
80
|
+
edges {
|
|
81
|
+
node {
|
|
82
|
+
blocks {
|
|
83
|
+
content {
|
|
84
|
+
props {
|
|
85
|
+
content {
|
|
86
|
+
props {
|
|
87
|
+
text
|
|
88
|
+
image {
|
|
89
|
+
desktop {
|
|
90
|
+
url
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
# type
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
root {
|
|
99
|
+
props {
|
|
100
|
+
author
|
|
101
|
+
datePublished
|
|
102
|
+
pageUrl
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
sliderBlogs: allBlogs(
|
|
110
|
+
limit: 9
|
|
111
|
+
sort: { blocks: { root: { props: { datePublished: DESC } } } }
|
|
112
|
+
) {
|
|
113
|
+
edges {
|
|
114
|
+
node {
|
|
115
|
+
blocks {
|
|
116
|
+
content {
|
|
117
|
+
props {
|
|
118
|
+
content {
|
|
119
|
+
props {
|
|
120
|
+
text
|
|
121
|
+
image {
|
|
122
|
+
desktop {
|
|
123
|
+
url
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
# type
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
root {
|
|
132
|
+
props {
|
|
133
|
+
author
|
|
134
|
+
datePublished
|
|
135
|
+
pageUrl
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
71
142
|
}
|
|
72
143
|
`;
|