popeye-cli 1.4.7 → 1.6.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/CHANGELOG.md +54 -0
- package/README.md +264 -63
- package/dist/adapters/gemini.d.ts +1 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +9 -4
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.d.ts +1 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +9 -4
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +35 -9
- package/dist/adapters/openai.js.map +1 -1
- package/dist/cli/commands/create.d.ts.map +1 -1
- package/dist/cli/commands/create.js +54 -4
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/interactive.d.ts +29 -0
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +132 -7
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/all.d.ts +8 -2
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +37 -316
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/doc-parser.d.ts +64 -0
- package/dist/generators/doc-parser.d.ts.map +1 -0
- package/dist/generators/doc-parser.js +407 -0
- package/dist/generators/doc-parser.js.map +1 -0
- package/dist/generators/frontend-design-analyzer.d.ts +30 -0
- package/dist/generators/frontend-design-analyzer.d.ts.map +1 -0
- package/dist/generators/frontend-design-analyzer.js +208 -0
- package/dist/generators/frontend-design-analyzer.js.map +1 -0
- package/dist/generators/shared-packages.d.ts +45 -0
- package/dist/generators/shared-packages.d.ts.map +1 -0
- package/dist/generators/shared-packages.js +456 -0
- package/dist/generators/shared-packages.js.map +1 -0
- package/dist/generators/templates/index.d.ts +8 -0
- package/dist/generators/templates/index.d.ts.map +1 -1
- package/dist/generators/templates/index.js +8 -0
- package/dist/generators/templates/index.js.map +1 -1
- package/dist/generators/templates/website-components.d.ts +33 -0
- package/dist/generators/templates/website-components.d.ts.map +1 -0
- package/dist/generators/templates/website-components.js +303 -0
- package/dist/generators/templates/website-components.js.map +1 -0
- package/dist/generators/templates/website-config.d.ts +55 -0
- package/dist/generators/templates/website-config.d.ts.map +1 -0
- package/dist/generators/templates/website-config.js +425 -0
- package/dist/generators/templates/website-config.js.map +1 -0
- package/dist/generators/templates/website-conversion.d.ts +27 -0
- package/dist/generators/templates/website-conversion.d.ts.map +1 -0
- package/dist/generators/templates/website-conversion.js +326 -0
- package/dist/generators/templates/website-conversion.js.map +1 -0
- package/dist/generators/templates/website-landing.d.ts +24 -0
- package/dist/generators/templates/website-landing.d.ts.map +1 -0
- package/dist/generators/templates/website-landing.js +276 -0
- package/dist/generators/templates/website-landing.js.map +1 -0
- package/dist/generators/templates/website-layout.d.ts +42 -0
- package/dist/generators/templates/website-layout.d.ts.map +1 -0
- package/dist/generators/templates/website-layout.js +408 -0
- package/dist/generators/templates/website-layout.js.map +1 -0
- package/dist/generators/templates/website-pricing.d.ts +11 -0
- package/dist/generators/templates/website-pricing.d.ts.map +1 -0
- package/dist/generators/templates/website-pricing.js +313 -0
- package/dist/generators/templates/website-pricing.js.map +1 -0
- package/dist/generators/templates/website-sections.d.ts +102 -0
- package/dist/generators/templates/website-sections.d.ts.map +1 -0
- package/dist/generators/templates/website-sections.js +444 -0
- package/dist/generators/templates/website-sections.js.map +1 -0
- package/dist/generators/templates/website-seo.d.ts +76 -0
- package/dist/generators/templates/website-seo.d.ts.map +1 -0
- package/dist/generators/templates/website-seo.js +326 -0
- package/dist/generators/templates/website-seo.js.map +1 -0
- package/dist/generators/templates/website.d.ts +10 -83
- package/dist/generators/templates/website.d.ts.map +1 -1
- package/dist/generators/templates/website.js +12 -875
- package/dist/generators/templates/website.js.map +1 -1
- package/dist/generators/website-content-scanner.d.ts +37 -0
- package/dist/generators/website-content-scanner.d.ts.map +1 -0
- package/dist/generators/website-content-scanner.js +165 -0
- package/dist/generators/website-content-scanner.js.map +1 -0
- package/dist/generators/website-context.d.ts +119 -0
- package/dist/generators/website-context.d.ts.map +1 -0
- package/dist/generators/website-context.js +350 -0
- package/dist/generators/website-context.js.map +1 -0
- package/dist/generators/website-debug.d.ts +68 -0
- package/dist/generators/website-debug.d.ts.map +1 -0
- package/dist/generators/website-debug.js +93 -0
- package/dist/generators/website-debug.js.map +1 -0
- package/dist/generators/website.d.ts +5 -0
- package/dist/generators/website.d.ts.map +1 -1
- package/dist/generators/website.js +136 -11
- package/dist/generators/website.js.map +1 -1
- package/dist/generators/workspace-root.d.ts +27 -0
- package/dist/generators/workspace-root.d.ts.map +1 -0
- package/dist/generators/workspace-root.js +100 -0
- package/dist/generators/workspace-root.js.map +1 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +40 -0
- package/dist/state/index.js.map +1 -1
- package/dist/types/consensus.d.ts +3 -0
- package/dist/types/consensus.d.ts.map +1 -1
- package/dist/types/consensus.js +1 -0
- package/dist/types/consensus.js.map +1 -1
- package/dist/types/website-strategy.d.ts +263 -0
- package/dist/types/website-strategy.d.ts.map +1 -0
- package/dist/types/website-strategy.js +105 -0
- package/dist/types/website-strategy.js.map +1 -0
- package/dist/types/workflow.d.ts +21 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +8 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/upgrade/handlers.d.ts +15 -0
- package/dist/upgrade/handlers.d.ts.map +1 -1
- package/dist/upgrade/handlers.js +52 -0
- package/dist/upgrade/handlers.js.map +1 -1
- package/dist/workflow/auto-fix-bundler.d.ts +37 -0
- package/dist/workflow/auto-fix-bundler.d.ts.map +1 -0
- package/dist/workflow/auto-fix-bundler.js +320 -0
- package/dist/workflow/auto-fix-bundler.js.map +1 -0
- package/dist/workflow/auto-fix.d.ts.map +1 -1
- package/dist/workflow/auto-fix.js +10 -3
- package/dist/workflow/auto-fix.js.map +1 -1
- package/dist/workflow/consensus.d.ts.map +1 -1
- package/dist/workflow/consensus.js +2 -0
- package/dist/workflow/consensus.js.map +1 -1
- package/dist/workflow/execution-mode.d.ts.map +1 -1
- package/dist/workflow/execution-mode.js +18 -0
- package/dist/workflow/execution-mode.js.map +1 -1
- package/dist/workflow/index.d.ts +4 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +37 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/overview.d.ts +89 -0
- package/dist/workflow/overview.d.ts.map +1 -0
- package/dist/workflow/overview.js +358 -0
- package/dist/workflow/overview.js.map +1 -0
- package/dist/workflow/plan-mode.d.ts +6 -4
- package/dist/workflow/plan-mode.d.ts.map +1 -1
- package/dist/workflow/plan-mode.js +148 -6
- package/dist/workflow/plan-mode.js.map +1 -1
- package/dist/workflow/website-strategy.d.ts +79 -0
- package/dist/workflow/website-strategy.d.ts.map +1 -0
- package/dist/workflow/website-strategy.js +310 -0
- package/dist/workflow/website-strategy.js.map +1 -0
- package/dist/workflow/website-updater.d.ts +17 -0
- package/dist/workflow/website-updater.d.ts.map +1 -0
- package/dist/workflow/website-updater.js +116 -0
- package/dist/workflow/website-updater.js.map +1 -0
- package/dist/workflow/workflow-logger.d.ts +1 -1
- package/dist/workflow/workflow-logger.d.ts.map +1 -1
- package/dist/workflow/workflow-logger.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/gemini.ts +10 -4
- package/src/adapters/grok.ts +10 -4
- package/src/adapters/openai.ts +38 -6
- package/src/cli/commands/create.ts +58 -4
- package/src/cli/interactive.ts +143 -7
- package/src/generators/all.ts +49 -332
- package/src/generators/doc-parser.ts +449 -0
- package/src/generators/frontend-design-analyzer.ts +261 -0
- package/src/generators/shared-packages.ts +500 -0
- package/src/generators/templates/index.ts +8 -0
- package/src/generators/templates/website-components.ts +330 -0
- package/src/generators/templates/website-config.ts +444 -0
- package/src/generators/templates/website-conversion.ts +341 -0
- package/src/generators/templates/website-landing.ts +331 -0
- package/src/generators/templates/website-layout.ts +443 -0
- package/src/generators/templates/website-pricing.ts +330 -0
- package/src/generators/templates/website-sections.ts +541 -0
- package/src/generators/templates/website-seo.ts +370 -0
- package/src/generators/templates/website.ts +38 -905
- package/src/generators/website-content-scanner.ts +208 -0
- package/src/generators/website-context.ts +493 -0
- package/src/generators/website-debug.ts +130 -0
- package/src/generators/website.ts +178 -20
- package/src/generators/workspace-root.ts +113 -0
- package/src/state/index.ts +56 -0
- package/src/types/consensus.ts +3 -0
- package/src/types/website-strategy.ts +243 -0
- package/src/types/workflow.ts +21 -0
- package/src/upgrade/handlers.ts +65 -0
- package/src/workflow/auto-fix-bundler.ts +392 -0
- package/src/workflow/auto-fix.ts +11 -3
- package/src/workflow/consensus.ts +2 -0
- package/src/workflow/execution-mode.ts +21 -0
- package/src/workflow/index.ts +37 -0
- package/src/workflow/overview.ts +475 -0
- package/src/workflow/plan-mode.ts +193 -8
- package/src/workflow/website-strategy.ts +379 -0
- package/src/workflow/website-updater.ts +142 -0
- package/src/workflow/workflow-logger.ts +1 -0
- package/tests/adapters/persona-switching.test.ts +63 -0
- package/tests/cli/project-naming.test.ts +136 -0
- package/tests/generators/doc-parser.test.ts +121 -0
- package/tests/generators/frontend-design-analyzer.test.ts +90 -0
- package/tests/generators/quality-gate.test.ts +183 -0
- package/tests/generators/shared-packages.test.ts +83 -0
- package/tests/generators/website-components.test.ts +159 -0
- package/tests/generators/website-config.test.ts +84 -0
- package/tests/generators/website-content-scanner.test.ts +181 -0
- package/tests/generators/website-context.test.ts +331 -0
- package/tests/generators/website-debug.test.ts +77 -0
- package/tests/generators/website-landing.test.ts +188 -0
- package/tests/generators/website-pricing.test.ts +98 -0
- package/tests/generators/website-sections.test.ts +245 -0
- package/tests/generators/website-seo-quality.test.ts +246 -0
- package/tests/generators/workspace-root.test.ts +105 -0
- package/tests/upgrade/handlers.test.ts +162 -0
- package/tests/workflow/auto-fix-bundler.test.ts +242 -0
- package/tests/workflow/overview.test.ts +392 -0
- package/tests/workflow/plan-mode.test.ts +111 -1
- package/tests/workflow/website-strategy.test.ts +246 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared website component templates
|
|
3
|
+
* Generates Header, Footer, and Navigation components with
|
|
4
|
+
* strategy-driven content, logo support, and mobile responsiveness
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Escape a string for safe use inside JSX template literals
|
|
8
|
+
*/
|
|
9
|
+
function escapeJsx(str) {
|
|
10
|
+
return str
|
|
11
|
+
.replace(/\\/g, '\\\\')
|
|
12
|
+
.replace(/'/g, "\\'")
|
|
13
|
+
.replace(/`/g, '\\`')
|
|
14
|
+
.replace(/\$/g, '\\$');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate website header component with logo, navigation, and CTA
|
|
18
|
+
*
|
|
19
|
+
* @param projectName - Project name for fallback display
|
|
20
|
+
* @param context - Optional content context
|
|
21
|
+
* @param strategy - Optional strategy for navigation and CTA
|
|
22
|
+
* @returns Header component source code
|
|
23
|
+
*/
|
|
24
|
+
export function generateWebsiteHeader(projectName, context, strategy) {
|
|
25
|
+
const displayName = context?.productName || projectName
|
|
26
|
+
.split('-')
|
|
27
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
28
|
+
.join(' ');
|
|
29
|
+
const hasLogo = !!(context?.brandAssets?.logoOutputPath || context?.brand?.logoPath);
|
|
30
|
+
// Reason: Next.js serves public/ at root, so public/brand/logo.svg -> /brand/logo.svg
|
|
31
|
+
const logoPath = context?.brandAssets?.logoOutputPath
|
|
32
|
+
? `/${context.brandAssets.logoOutputPath.replace(/^public\//, '')}`
|
|
33
|
+
: '/brand/logo.svg';
|
|
34
|
+
// Build nav items from strategy or defaults
|
|
35
|
+
const navItems = strategy?.siteArchitecture.navigation || [
|
|
36
|
+
{ label: 'Features', href: '/#features' },
|
|
37
|
+
{ label: 'Pricing', href: '/pricing' },
|
|
38
|
+
{ label: 'Docs', href: '/docs' },
|
|
39
|
+
{ label: 'Blog', href: '/blog' },
|
|
40
|
+
];
|
|
41
|
+
const navItemsStr = navItems
|
|
42
|
+
.map(item => ` { label: '${escapeJsx(item.label)}', href: '${escapeJsx(item.href)}' }`)
|
|
43
|
+
.join(',\n');
|
|
44
|
+
// CTA from strategy or default
|
|
45
|
+
const ctaText = strategy?.conversionStrategy.primaryCta.text || 'Get Started';
|
|
46
|
+
const ctaHref = strategy?.conversionStrategy.primaryCta.href || '/pricing';
|
|
47
|
+
// Logo rendering: Image if available, product initial circle if not
|
|
48
|
+
const initialLetter = displayName.charAt(0).toUpperCase();
|
|
49
|
+
const logoBlock = hasLogo
|
|
50
|
+
? `<Image src="${logoPath}" alt="${escapeJsx(displayName)}" width={32} height={32} className="h-8 w-auto" />`
|
|
51
|
+
: `<div className="flex items-center gap-2">
|
|
52
|
+
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary-600 text-sm font-bold text-white">${initialLetter}</div>
|
|
53
|
+
<span className="text-lg font-bold text-foreground">${escapeJsx(displayName)}</span>
|
|
54
|
+
</div>`;
|
|
55
|
+
return `'use client';
|
|
56
|
+
|
|
57
|
+
import { useState } from 'react';
|
|
58
|
+
import Link from 'next/link';
|
|
59
|
+
${hasLogo ? "import Image from 'next/image';" : ''}
|
|
60
|
+
|
|
61
|
+
const NAV_ITEMS = [
|
|
62
|
+
${navItemsStr}
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Site header with logo, navigation links, mobile menu, and CTA
|
|
67
|
+
*/
|
|
68
|
+
export default function Header() {
|
|
69
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<header className="sticky top-0 z-50 border-b border-gray-200 bg-white/80 backdrop-blur-sm">
|
|
73
|
+
<nav className="container flex h-16 items-center justify-between">
|
|
74
|
+
{/* Logo */}
|
|
75
|
+
<Link href="/" className="flex items-center gap-2">
|
|
76
|
+
${logoBlock}
|
|
77
|
+
</Link>
|
|
78
|
+
|
|
79
|
+
{/* Desktop Navigation */}
|
|
80
|
+
<div className="hidden items-center gap-8 md:flex">
|
|
81
|
+
{NAV_ITEMS.map((item) => (
|
|
82
|
+
<Link
|
|
83
|
+
key={item.href}
|
|
84
|
+
href={item.href}
|
|
85
|
+
className="text-sm font-medium text-gray-700 hover:text-primary-600 transition-colors"
|
|
86
|
+
>
|
|
87
|
+
{item.label}
|
|
88
|
+
</Link>
|
|
89
|
+
))}
|
|
90
|
+
<Link
|
|
91
|
+
href="${escapeJsx(ctaHref)}"
|
|
92
|
+
className="rounded-md bg-primary-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-primary-500 transition-colors"
|
|
93
|
+
>
|
|
94
|
+
${escapeJsx(ctaText)}
|
|
95
|
+
</Link>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
{/* Mobile Menu Button */}
|
|
99
|
+
<button
|
|
100
|
+
type="button"
|
|
101
|
+
className="md:hidden rounded-md p-2 text-gray-700"
|
|
102
|
+
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
103
|
+
aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
|
|
104
|
+
aria-expanded={mobileMenuOpen}
|
|
105
|
+
>
|
|
106
|
+
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
|
|
107
|
+
{mobileMenuOpen ? (
|
|
108
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
109
|
+
) : (
|
|
110
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
|
111
|
+
)}
|
|
112
|
+
</svg>
|
|
113
|
+
</button>
|
|
114
|
+
</nav>
|
|
115
|
+
|
|
116
|
+
{/* Mobile Menu */}
|
|
117
|
+
{mobileMenuOpen && (
|
|
118
|
+
<div className="border-t border-gray-200 bg-white px-4 py-4 md:hidden">
|
|
119
|
+
<div className="flex flex-col gap-4">
|
|
120
|
+
{NAV_ITEMS.map((item) => (
|
|
121
|
+
<Link
|
|
122
|
+
key={item.href}
|
|
123
|
+
href={item.href}
|
|
124
|
+
className="text-sm font-medium text-gray-700 hover:text-primary-600"
|
|
125
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
126
|
+
>
|
|
127
|
+
{item.label}
|
|
128
|
+
</Link>
|
|
129
|
+
))}
|
|
130
|
+
<Link
|
|
131
|
+
href="${escapeJsx(ctaHref)}"
|
|
132
|
+
className="rounded-md bg-primary-600 px-4 py-2 text-center text-sm font-semibold text-white"
|
|
133
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
134
|
+
>
|
|
135
|
+
${escapeJsx(ctaText)}
|
|
136
|
+
</Link>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
)}
|
|
140
|
+
</header>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Generate website footer component with multi-column sections
|
|
147
|
+
*
|
|
148
|
+
* @param projectName - Project name for copyright
|
|
149
|
+
* @param context - Optional content context
|
|
150
|
+
* @param strategy - Optional strategy for footer sections
|
|
151
|
+
* @returns Footer component source code
|
|
152
|
+
*/
|
|
153
|
+
export function generateWebsiteFooter(projectName, context, strategy) {
|
|
154
|
+
const displayName = context?.productName || projectName
|
|
155
|
+
.split('-')
|
|
156
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
157
|
+
.join(' ');
|
|
158
|
+
// Build footer sections from strategy or defaults
|
|
159
|
+
const sections = strategy?.siteArchitecture.footerSections || [
|
|
160
|
+
{
|
|
161
|
+
title: 'Product',
|
|
162
|
+
links: [
|
|
163
|
+
{ label: 'Features', href: '/#features' },
|
|
164
|
+
{ label: 'Pricing', href: '/pricing' },
|
|
165
|
+
{ label: 'Documentation', href: '/docs' },
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
title: 'Resources',
|
|
170
|
+
links: [
|
|
171
|
+
{ label: 'Blog', href: '/blog' },
|
|
172
|
+
{ label: 'Support', href: '/contact' },
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
title: 'Legal',
|
|
177
|
+
links: [
|
|
178
|
+
{ label: 'Privacy Policy', href: '/privacy' },
|
|
179
|
+
{ label: 'Terms of Service', href: '/terms' },
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
const sectionsStr = sections
|
|
184
|
+
.map(section => {
|
|
185
|
+
const linksStr = section.links
|
|
186
|
+
.map(link => ` { label: '${escapeJsx(link.label)}', href: '${escapeJsx(link.href)}' }`)
|
|
187
|
+
.join(',\n');
|
|
188
|
+
return ` {\n title: '${escapeJsx(section.title)}',\n links: [\n${linksStr}\n ],\n }`;
|
|
189
|
+
})
|
|
190
|
+
.join(',\n');
|
|
191
|
+
return `import Link from 'next/link';
|
|
192
|
+
|
|
193
|
+
const FOOTER_SECTIONS = [
|
|
194
|
+
${sectionsStr}
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Site footer with multi-column link sections and copyright
|
|
199
|
+
*/
|
|
200
|
+
export default function Footer() {
|
|
201
|
+
return (
|
|
202
|
+
<footer className="border-t border-border bg-muted/50">
|
|
203
|
+
<div className="container py-12">
|
|
204
|
+
<div className="grid grid-cols-2 gap-8 md:grid-cols-${Math.min(sections.length + 1, 4)}">
|
|
205
|
+
{/* Brand column */}
|
|
206
|
+
<div className="col-span-2 md:col-span-1">
|
|
207
|
+
<Link href="/" className="text-lg font-bold text-foreground">
|
|
208
|
+
${escapeJsx(displayName)}
|
|
209
|
+
</Link>
|
|
210
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
211
|
+
${context?.tagline ? escapeJsx(context.tagline) : 'Build something amazing.'}
|
|
212
|
+
</p>
|
|
213
|
+
{/* Newsletter */}
|
|
214
|
+
<form className="mt-6" onSubmit={(e) => e.preventDefault()}>
|
|
215
|
+
<label htmlFor="newsletter-email" className="text-sm font-medium text-foreground">
|
|
216
|
+
Stay updated
|
|
217
|
+
</label>
|
|
218
|
+
<div className="mt-2 flex gap-2">
|
|
219
|
+
<input
|
|
220
|
+
id="newsletter-email"
|
|
221
|
+
type="email"
|
|
222
|
+
placeholder="you@example.com"
|
|
223
|
+
className="flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary-600"
|
|
224
|
+
/>
|
|
225
|
+
<button
|
|
226
|
+
type="submit"
|
|
227
|
+
className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white hover:bg-primary-500 transition-colors"
|
|
228
|
+
>
|
|
229
|
+
Subscribe
|
|
230
|
+
</button>
|
|
231
|
+
</div>
|
|
232
|
+
</form>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
{/* Link columns */}
|
|
236
|
+
{FOOTER_SECTIONS.map((section) => (
|
|
237
|
+
<div key={section.title}>
|
|
238
|
+
<h3 className="text-sm font-semibold text-foreground">{section.title}</h3>
|
|
239
|
+
<ul className="mt-4 space-y-2">
|
|
240
|
+
{section.links.map((link) => (
|
|
241
|
+
<li key={link.href}>
|
|
242
|
+
<Link
|
|
243
|
+
href={link.href}
|
|
244
|
+
className="text-sm text-muted-foreground hover:text-primary-600 transition-colors"
|
|
245
|
+
>
|
|
246
|
+
{link.label}
|
|
247
|
+
</Link>
|
|
248
|
+
</li>
|
|
249
|
+
))}
|
|
250
|
+
</ul>
|
|
251
|
+
</div>
|
|
252
|
+
))}
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
<div className="mt-12 border-t border-border pt-8">
|
|
256
|
+
<p className="text-center text-sm text-muted-foreground">
|
|
257
|
+
© {new Date().getFullYear()} ${escapeJsx(displayName)}. All rights reserved.
|
|
258
|
+
</p>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
</footer>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
`;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Generate navigation config module
|
|
268
|
+
*
|
|
269
|
+
* @param strategy - Optional strategy for navigation items
|
|
270
|
+
* @returns Navigation config source code
|
|
271
|
+
*/
|
|
272
|
+
export function generateWebsiteNavigation(strategy) {
|
|
273
|
+
const navItems = strategy?.siteArchitecture.navigation || [
|
|
274
|
+
{ label: 'Features', href: '/#features' },
|
|
275
|
+
{ label: 'Pricing', href: '/pricing' },
|
|
276
|
+
{ label: 'Docs', href: '/docs' },
|
|
277
|
+
{ label: 'Blog', href: '/blog' },
|
|
278
|
+
];
|
|
279
|
+
const itemsStr = navItems
|
|
280
|
+
.map(item => {
|
|
281
|
+
const childrenStr = item.children && item.children.length > 0
|
|
282
|
+
? `,\n children: [\n${item.children.map(c => ` { label: '${escapeJsx(c.label)}', href: '${escapeJsx(c.href)}' }`).join(',\n')}\n ]`
|
|
283
|
+
: '';
|
|
284
|
+
return ` { label: '${escapeJsx(item.label)}', href: '${escapeJsx(item.href)}'${childrenStr} }`;
|
|
285
|
+
})
|
|
286
|
+
.join(',\n');
|
|
287
|
+
return `/**
|
|
288
|
+
* Navigation configuration
|
|
289
|
+
* Exported for use in Header and mobile navigation components
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
export interface NavItem {
|
|
293
|
+
label: string;
|
|
294
|
+
href: string;
|
|
295
|
+
children?: NavItem[];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export const NAV_ITEMS: NavItem[] = [
|
|
299
|
+
${itemsStr}
|
|
300
|
+
];
|
|
301
|
+
`;
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=website-components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"website-components.js","sourceRoot":"","sources":["../../../src/generators/templates/website-components.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Website configuration templates (non-content)
|
|
3
|
+
* Package configs, build tools, Docker, vitest, and env declarations
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generate Next.js package.json
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateWebsitePackageJson(projectName: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate Next.js config
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateNextConfig(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate website tsconfig.json
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateWebsiteTsconfig(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Options for generating the Tailwind config
|
|
19
|
+
*/
|
|
20
|
+
export interface TailwindConfigOptions {
|
|
21
|
+
/** Primary brand color (hex) to generate color scale from */
|
|
22
|
+
primaryColor?: string;
|
|
23
|
+
/** Whether to import workspace design-tokens preset */
|
|
24
|
+
workspaceMode?: boolean;
|
|
25
|
+
/** Project name (for workspace preset import path) */
|
|
26
|
+
projectName?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Generate Tailwind config for website
|
|
30
|
+
*
|
|
31
|
+
* @param options - Optional configuration for brand colors and workspace mode
|
|
32
|
+
* @returns Tailwind config source code
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateWebsiteTailwindConfig(options?: TailwindConfigOptions): string;
|
|
35
|
+
/**
|
|
36
|
+
* Generate PostCSS config for website
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateWebsitePostcssConfig(): string;
|
|
39
|
+
/**
|
|
40
|
+
* Generate website Dockerfile
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateWebsiteDockerfile(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Generate vitest config for website
|
|
45
|
+
*/
|
|
46
|
+
export declare function generateWebsiteVitestConfig(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Generate vitest setup for website
|
|
49
|
+
*/
|
|
50
|
+
export declare function generateWebsiteVitestSetup(): string;
|
|
51
|
+
/**
|
|
52
|
+
* Generate Next.js environment declaration
|
|
53
|
+
*/
|
|
54
|
+
export declare function generateWebsiteNextEnv(): string;
|
|
55
|
+
//# sourceMappingURL=website-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"website-config.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/website-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqCtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAwC3C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CA6BhD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CA4ErF;AAmGD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAQrD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA4ClD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAoBpD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAsBnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAO/C"}
|