react-layout-sdk 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/init.js +76 -66
  2. package/package.json +1 -1
package/bin/init.js CHANGED
@@ -3,24 +3,29 @@ const fs = require('fs');
3
3
  const path = require('path');
4
4
 
5
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]]');
6
+
7
+ // Detect project structure
8
+ const hasSrc = fs.existsSync(path.join(projectRoot, 'src'));
9
+ const basePath = hasSrc ? path.join(projectRoot, 'src') : projectRoot;
10
+
11
+ const componentsDir = path.join(basePath, 'components');
12
+ const hasAppRouter = fs.existsSync(path.join(basePath, 'app'));
13
+ const hasPagesRouter = fs.existsSync(path.join(basePath, 'pages'));
14
+
15
+ if (!hasAppRouter && !hasPagesRouter) {
16
+ console.error("āŒ Could not find an 'app' or 'pages' directory. Make sure you are running this in the root of a Next.js project.");
17
+ process.exit(1);
18
+ }
10
19
 
11
20
  // Helper to ensure directory exists
12
21
  function ensureDirSync(dirPath) {
13
22
  if (!fs.existsSync(dirPath)) {
14
23
  fs.mkdirSync(dirPath, { recursive: true });
15
- console.log(`Created directory: ${dirPath}`);
24
+ console.log(`šŸ“ Created directory: ${dirPath}`);
16
25
  }
17
26
  }
18
27
 
19
- // Ensure base directories exist
20
- ensureDirSync(srcDir);
21
28
  ensureDirSync(componentsDir);
22
- ensureDirSync(appDir);
23
- ensureDirSync(pageDir);
24
29
 
25
30
  // 1. Create factory.ts
26
31
  const factoryPath = path.join(componentsDir, 'factory.ts');
@@ -34,9 +39,7 @@ export const componentMap = {
34
39
  `;
35
40
  if (!fs.existsSync(factoryPath)) {
36
41
  fs.writeFileSync(factoryPath, factoryContent);
37
- console.log('āœ… Created src/components/factory.ts');
38
- } else {
39
- console.log('āš ļø src/components/factory.ts already exists, skipping.');
42
+ console.log('āœ… Created components/factory.ts');
40
43
  }
41
44
 
42
45
  // 2. Create Header.tsx
@@ -54,9 +57,6 @@ export default function Header(props: any) {
54
57
  {logoUrl && <img src={logoUrl} alt="Logo" width="40" />}
55
58
  <h1 style={{ margin: 0, fontSize: '1.5rem' }}>{title}</h1>
56
59
  </div>
57
- <nav>
58
- {/* Navigation links will go here */}
59
- </nav>
60
60
  </div>
61
61
  </header>
62
62
  );
@@ -64,9 +64,7 @@ export default function Header(props: any) {
64
64
  `;
65
65
  if (!fs.existsSync(headerPath)) {
66
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.');
67
+ console.log('āœ… Created components/Header.tsx');
70
68
  }
71
69
 
72
70
  // 3. Create Footer.tsx
@@ -75,7 +73,6 @@ const footerContent = `import React from 'react';
75
73
 
76
74
  export default function Footer(props: any) {
77
75
  const text = props?.text || 'Ā© 2026 Velox Layout';
78
-
79
76
  return (
80
77
  <footer style={{ padding: '20px', background: '#333', color: '#fff', textAlign: 'center', marginTop: '40px' }}>
81
78
  <p style={{ margin: 0 }}>{text}</p>
@@ -85,77 +82,90 @@ export default function Footer(props: any) {
85
82
  `;
86
83
  if (!fs.existsSync(footerPath)) {
87
84
  fs.writeFileSync(footerPath, footerContent);
88
- console.log('āœ… Created src/components/Footer.tsx');
89
- } else {
90
- console.log('āš ļø src/components/Footer.tsx already exists, skipping.');
85
+ console.log('āœ… Created components/Footer.tsx');
91
86
  }
92
87
 
93
- // 4. Create app/[[...slug]]/page.tsx
94
- const pagePath = path.join(pageDir, 'page.tsx');
95
- const pageContent = `import React from 'react';
88
+ // 4. Generate Page routing
89
+ if (hasAppRouter) {
90
+ console.log('šŸ” Detected Next.js App Router');
91
+ const pageDir = path.join(basePath, 'app', '[[...slug]]');
92
+ ensureDirSync(pageDir);
93
+
94
+ const appPagePath = path.join(pageDir, 'page.tsx');
95
+ const appPageContent = `import React from 'react';
96
96
  import { fetchVeloxLayout, Placeholder } from 'react-layout-sdk';
97
97
  import { componentMap } from '@/components/factory';
98
98
 
99
99
  export default async function Page({ params }: { params: { slug?: string[] } }) {
100
100
  const slugArray = params.slug || [];
101
101
  const path = slugArray.join('/') || '/';
102
-
103
- // Make sure to replace this URL with your actual Strapi URL
104
102
  const STRAPI_URL = process.env.NEXT_PUBLIC_STRAPI_URL || 'http://localhost:1337';
105
103
 
106
104
  try {
107
105
  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
- }
106
+ if (!layoutData || !layoutData.strapi) return <h1>404 - Not Found</h1>;
117
107
 
118
108
  const { route } = layoutData.strapi;
119
109
 
120
110
  return (
121
111
  <div className="layout-wrapper">
122
- <Placeholder
123
- name="header"
124
- rendering={route.placeholders.header || []}
125
- componentMap={componentMap}
126
- />
127
-
112
+ <Placeholder name="header" rendering={route.placeholders.header || []} componentMap={componentMap} />
128
113
  <main style={{ minHeight: '60vh', padding: '20px' }}>
129
- <Placeholder
130
- name="main"
131
- rendering={route.placeholders.main || []}
132
- componentMap={componentMap}
133
- />
114
+ <Placeholder name="main" rendering={route.placeholders.main || []} componentMap={componentMap} />
134
115
  </main>
135
-
136
- <Placeholder
137
- name="footer"
138
- rendering={route.placeholders.footer || []}
139
- componentMap={componentMap}
140
- />
116
+ <Placeholder name="footer" rendering={route.placeholders.footer || []} componentMap={componentMap} />
141
117
  </div>
142
118
  );
143
119
  } 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
- );
120
+ return <h1>Error Loading Layout</h1>;
121
+ }
122
+ }
123
+ `;
124
+ if (!fs.existsSync(appPagePath)) {
125
+ fs.writeFileSync(appPagePath, appPageContent);
126
+ console.log('āœ… Created app/[[...slug]]/page.tsx');
127
+ }
128
+ } else if (hasPagesRouter) {
129
+ console.log('šŸ” Detected Next.js Pages Router');
130
+ const pagePath = path.join(basePath, 'pages', '[[...slug]].tsx');
131
+ const pagesContent = `import React from 'react';
132
+ import { fetchVeloxLayout, Placeholder } from 'react-layout-sdk';
133
+ import { componentMap } from '@/components/factory';
134
+
135
+ export default function LayoutPage({ layoutData, error }: any) {
136
+ if (error || !layoutData?.strapi) return <h1>404 - Layout Not Found</h1>;
137
+
138
+ const { route } = layoutData.strapi;
139
+ return (
140
+ <div className="layout-wrapper">
141
+ <Placeholder name="header" rendering={route.placeholders.header || []} componentMap={componentMap} />
142
+ <main style={{ minHeight: '60vh', padding: '20px' }}>
143
+ <Placeholder name="main" rendering={route.placeholders.main || []} componentMap={componentMap} />
144
+ </main>
145
+ <Placeholder name="footer" rendering={route.placeholders.footer || []} componentMap={componentMap} />
146
+ </div>
147
+ );
148
+ }
149
+
150
+ export async function getServerSideProps(context: any) {
151
+ const slugArray = context.params?.slug || [];
152
+ const path = slugArray.join('/') || '/';
153
+ const STRAPI_URL = process.env.NEXT_PUBLIC_STRAPI_URL || 'http://localhost:1337';
154
+
155
+ try {
156
+ const layoutData = await fetchVeloxLayout(STRAPI_URL, path, 'en');
157
+ if (!layoutData) return { notFound: true };
158
+
159
+ return { props: { layoutData } };
160
+ } catch (error) {
161
+ return { props: { error: true } };
151
162
  }
152
163
  }
153
164
  `;
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.');
165
+ if (!fs.existsSync(pagePath)) {
166
+ fs.writeFileSync(pagePath, pagesContent);
167
+ console.log('āœ… Created pages/[[...slug]].tsx');
168
+ }
159
169
  }
160
170
 
161
- console.log('\\nšŸš€ Layout setup complete! Please verify your Strapi URL in src/app/[[...slug]]/page.tsx.');
171
+ console.log('\nšŸš€ Layout setup complete! Please verify your Strapi URL in your routing page.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-layout-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "React components for Velox SDK (Sitecore-like routing)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",