react-layout-sdk 1.0.0 → 1.1.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.
- package/bin/init.js +161 -0
- package/package.json +4 -1
package/bin/init.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const projectRoot = process.cwd();
|
|
6
|
+
const srcDir = path.join(projectRoot, 'src');
|
|
7
|
+
const componentsDir = path.join(srcDir, 'components');
|
|
8
|
+
const appDir = path.join(srcDir, 'app');
|
|
9
|
+
const pageDir = path.join(appDir, '[[...slug]]');
|
|
10
|
+
|
|
11
|
+
// Helper to ensure directory exists
|
|
12
|
+
function ensureDirSync(dirPath) {
|
|
13
|
+
if (!fs.existsSync(dirPath)) {
|
|
14
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
15
|
+
console.log(`Created directory: ${dirPath}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Ensure base directories exist
|
|
20
|
+
ensureDirSync(srcDir);
|
|
21
|
+
ensureDirSync(componentsDir);
|
|
22
|
+
ensureDirSync(appDir);
|
|
23
|
+
ensureDirSync(pageDir);
|
|
24
|
+
|
|
25
|
+
// 1. Create factory.ts
|
|
26
|
+
const factoryPath = path.join(componentsDir, 'factory.ts');
|
|
27
|
+
const factoryContent = `import Header from './Header';
|
|
28
|
+
import Footer from './Footer';
|
|
29
|
+
|
|
30
|
+
export const componentMap = {
|
|
31
|
+
'velox.header': Header,
|
|
32
|
+
'velox.footer': Footer,
|
|
33
|
+
};
|
|
34
|
+
`;
|
|
35
|
+
if (!fs.existsSync(factoryPath)) {
|
|
36
|
+
fs.writeFileSync(factoryPath, factoryContent);
|
|
37
|
+
console.log('✅ Created src/components/factory.ts');
|
|
38
|
+
} else {
|
|
39
|
+
console.log('⚠️ src/components/factory.ts already exists, skipping.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Create Header.tsx
|
|
43
|
+
const headerPath = path.join(componentsDir, 'Header.tsx');
|
|
44
|
+
const headerContent = `import React from 'react';
|
|
45
|
+
|
|
46
|
+
export default function Header(props: any) {
|
|
47
|
+
const title = props?.title || 'Velox Header';
|
|
48
|
+
const logoUrl = props?.logoUrl;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<header style={{ padding: '20px', background: '#f5f5f5', borderBottom: '1px solid #ddd' }}>
|
|
52
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
|
53
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
|
54
|
+
{logoUrl && <img src={logoUrl} alt="Logo" width="40" />}
|
|
55
|
+
<h1 style={{ margin: 0, fontSize: '1.5rem' }}>{title}</h1>
|
|
56
|
+
</div>
|
|
57
|
+
<nav>
|
|
58
|
+
{/* Navigation links will go here */}
|
|
59
|
+
</nav>
|
|
60
|
+
</div>
|
|
61
|
+
</header>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
if (!fs.existsSync(headerPath)) {
|
|
66
|
+
fs.writeFileSync(headerPath, headerContent);
|
|
67
|
+
console.log('✅ Created src/components/Header.tsx');
|
|
68
|
+
} else {
|
|
69
|
+
console.log('⚠️ src/components/Header.tsx already exists, skipping.');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 3. Create Footer.tsx
|
|
73
|
+
const footerPath = path.join(componentsDir, 'Footer.tsx');
|
|
74
|
+
const footerContent = `import React from 'react';
|
|
75
|
+
|
|
76
|
+
export default function Footer(props: any) {
|
|
77
|
+
const text = props?.text || '© 2026 Velox Layout';
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<footer style={{ padding: '20px', background: '#333', color: '#fff', textAlign: 'center', marginTop: '40px' }}>
|
|
81
|
+
<p style={{ margin: 0 }}>{text}</p>
|
|
82
|
+
</footer>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
if (!fs.existsSync(footerPath)) {
|
|
87
|
+
fs.writeFileSync(footerPath, footerContent);
|
|
88
|
+
console.log('✅ Created src/components/Footer.tsx');
|
|
89
|
+
} else {
|
|
90
|
+
console.log('⚠️ src/components/Footer.tsx already exists, skipping.');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 4. Create app/[[...slug]]/page.tsx
|
|
94
|
+
const pagePath = path.join(pageDir, 'page.tsx');
|
|
95
|
+
const pageContent = `import React from 'react';
|
|
96
|
+
import { fetchVeloxLayout, Placeholder } from 'react-layout-sdk';
|
|
97
|
+
import { componentMap } from '@/components/factory';
|
|
98
|
+
|
|
99
|
+
export default async function Page({ params }: { params: { slug?: string[] } }) {
|
|
100
|
+
const slugArray = params.slug || [];
|
|
101
|
+
const path = slugArray.join('/') || '/';
|
|
102
|
+
|
|
103
|
+
// Make sure to replace this URL with your actual Strapi URL
|
|
104
|
+
const STRAPI_URL = process.env.NEXT_PUBLIC_STRAPI_URL || 'http://localhost:1337';
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const layoutData = await fetchVeloxLayout(STRAPI_URL, path, 'en');
|
|
108
|
+
|
|
109
|
+
if (!layoutData || !layoutData.strapi) {
|
|
110
|
+
return (
|
|
111
|
+
<div style={{ textAlign: 'center', padding: '50px' }}>
|
|
112
|
+
<h1>404 - Page/Layout Not Found</h1>
|
|
113
|
+
<p>Could not fetch layout for path: {path}</p>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const { route } = layoutData.strapi;
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div className="layout-wrapper">
|
|
122
|
+
<Placeholder
|
|
123
|
+
name="header"
|
|
124
|
+
rendering={route.placeholders.header || []}
|
|
125
|
+
componentMap={componentMap}
|
|
126
|
+
/>
|
|
127
|
+
|
|
128
|
+
<main style={{ minHeight: '60vh', padding: '20px' }}>
|
|
129
|
+
<Placeholder
|
|
130
|
+
name="main"
|
|
131
|
+
rendering={route.placeholders.main || []}
|
|
132
|
+
componentMap={componentMap}
|
|
133
|
+
/>
|
|
134
|
+
</main>
|
|
135
|
+
|
|
136
|
+
<Placeholder
|
|
137
|
+
name="footer"
|
|
138
|
+
rendering={route.placeholders.footer || []}
|
|
139
|
+
componentMap={componentMap}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error('Error fetching layout:', error);
|
|
145
|
+
return (
|
|
146
|
+
<div style={{ textAlign: 'center', padding: '50px', color: 'red' }}>
|
|
147
|
+
<h1>Error Loading Layout</h1>
|
|
148
|
+
<p>Please check your Strapi server connection.</p>
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
if (!fs.existsSync(pagePath)) {
|
|
155
|
+
fs.writeFileSync(pagePath, pageContent);
|
|
156
|
+
console.log('✅ Created src/app/[[...slug]]/page.tsx');
|
|
157
|
+
} else {
|
|
158
|
+
console.log('⚠️ src/app/[[...slug]]/page.tsx already exists, skipping.');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('\\n🚀 Layout setup complete! Please verify your Strapi URL in src/app/[[...slug]]/page.tsx.');
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-layout-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "React components for Velox SDK (Sitecore-like routing)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"react-layout-sdk": "./bin/init.js"
|
|
10
|
+
},
|
|
8
11
|
"peerDependencies": {
|
|
9
12
|
"react": ">=18.0.0",
|
|
10
13
|
"react-dom": ">=18.0.0"
|