kofi-stack-template-generator 2.1.22 → 2.1.24

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/index.js CHANGED
@@ -579,7 +579,26 @@ GCS_CREDENTIALS="{}" # JSON service account key
579
579
  }
580
580
  `,
581
581
  "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
582
- "marketing/payload/src/app/(frontend)/layout.tsx.hbs": "export default function FrontendLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return <>{children}</>\n}\n",
582
+ "marketing/payload/src/app/(frontend)/layout.tsx.hbs": `import type { Metadata } from 'next'
583
+ import '../globals.css'
584
+
585
+ export const metadata: Metadata = {
586
+ title: '{{projectName}} - Marketing',
587
+ description: 'Built with Payload CMS and Next.js',
588
+ }
589
+
590
+ export default function FrontendLayout({
591
+ children,
592
+ }: {
593
+ children: React.ReactNode
594
+ }) {
595
+ return (
596
+ <html lang="en">
597
+ <body>{children}</body>
598
+ </html>
599
+ )
600
+ }
601
+ `,
583
602
  "marketing/payload/src/app/(frontend)/page.tsx.hbs": `import { getPayload } from 'payload'
584
603
  import config from '@/payload.config'
585
604
 
@@ -673,26 +692,7 @@ export default async function HomePage() {
673
692
  "marketing/payload/src/app/(payload)/importMap.js.hbs": "export const importMap = {}\n",
674
693
  "marketing/payload/src/app/(payload)/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport config from '@/payload.config'\nimport { RootLayout, handleServerFunctions } from '@payloadcms/next/layouts'\nimport type { ServerFunctionClient } from 'payload'\nimport { importMap } from './importMap.js'\nimport './custom.scss'\n\nexport const metadata: Metadata = {\n title: 'Admin Panel',\n}\n\ntype LayoutArgs = {\n children: React.ReactNode\n}\n\nconst serverFunction: ServerFunctionClient = async function (args) {\n 'use server'\n return handleServerFunctions({ ...args, config, importMap })\n}\n\nconst Layout = ({ children }: LayoutArgs) =>\n RootLayout({ children, config, importMap, serverFunction })\n\nexport default Layout\n",
675
694
  "marketing/payload/src/app/globals.css.hbs": '@import "tailwindcss";\n\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --font-sans: var(--font-geist-sans);\n --font-mono: var(--font-geist-mono);\n --color-ring: var(--ring);\n --color-input: var(--input);\n --color-border: var(--border);\n --color-destructive: var(--destructive);\n --color-accent-foreground: var(--accent-foreground);\n --color-accent: var(--accent);\n --color-muted-foreground: var(--muted-foreground);\n --color-muted: var(--muted);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-secondary: var(--secondary);\n --color-primary-foreground: var(--primary-foreground);\n --color-primary: var(--primary);\n --color-popover-foreground: var(--popover-foreground);\n --color-popover: var(--popover);\n --color-card-foreground: var(--card-foreground);\n --color-card: var(--card);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n:root {\n --radius: 0.625rem;\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n\n body {\n @apply bg-background text-foreground;\n }\n}\n',
676
- "marketing/payload/src/app/layout.tsx.hbs": `import type { Metadata } from 'next'
677
- import './globals.css'
678
-
679
- export const metadata: Metadata = {
680
- title: 'Marketing Site',
681
- description: 'Built with Payload CMS',
682
- }
683
-
684
- export default function RootLayout({
685
- children,
686
- }: {
687
- children: React.ReactNode
688
- }) {
689
- return (
690
- <html lang="en">
691
- <body>{children}</body>
692
- </html>
693
- )
694
- }
695
- `,
695
+ "marketing/payload/src/app/layout.tsx.hbs": "// Root layout is minimal - each route group has its own complete layout\n// This prevents nested <html>/<body> tags between frontend and Payload admin\n// CSS is imported in each route group's layout to avoid style conflicts\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return children\n}\n",
696
696
  "marketing/payload/src/blocks/Benefits.ts.hbs": "import type { Block } from 'payload'\n\nexport const BenefitsBlock: Block = {\n slug: 'benefits',\n labels: { singular: 'Benefits', plural: 'Benefits' },\n fields: [\n { name: 'label', type: 'text' },\n { name: 'heading', type: 'text', required: true },\n { name: 'description', type: 'textarea' },\n { name: 'image', type: 'upload', relationTo: 'media' },\n {\n name: 'imagePosition',\n type: 'select',\n options: [\n { label: 'Left', value: 'left' },\n { label: 'Right', value: 'right' },\n ],\n defaultValue: 'right',\n },\n {\n name: 'benefits',\n type: 'array',\n fields: [{ name: 'text', type: 'text', required: true }],\n },\n {\n name: 'cta',\n type: 'group',\n fields: [\n { name: 'label', type: 'text' },\n { name: 'url', type: 'text' },\n ],\n },\n ],\n}\n",
697
697
  "marketing/payload/src/blocks/CTA.ts.hbs": "import type { Block } from 'payload'\n\nexport const CTABlock: Block = {\n slug: 'cta',\n labels: { singular: 'CTA', plural: 'CTAs' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'description', type: 'textarea' },\n {\n name: 'style',\n type: 'select',\n options: [\n { label: 'Light', value: 'light' },\n { label: 'Dark', value: 'dark' },\n { label: 'Primary', value: 'primary' },\n ],\n defaultValue: 'dark',\n },\n {\n name: 'buttons',\n type: 'array',\n maxRows: 2,\n fields: [\n { name: 'label', type: 'text', required: true },\n { name: 'url', type: 'text', required: true },\n {\n name: 'variant',\n type: 'select',\n options: [\n { label: 'Primary', value: 'primary' },\n { label: 'Secondary', value: 'secondary' },\n { label: 'Outline', value: 'outline' },\n ],\n defaultValue: 'primary',\n },\n ],\n },\n ],\n}\n",
698
698
  "marketing/payload/src/blocks/Content.ts.hbs": "import type { Block } from 'payload'\n\nexport const ContentBlock: Block = {\n slug: 'content',\n labels: { singular: 'Content', plural: 'Content' },\n fields: [\n { name: 'content', type: 'richText' },\n ],\n}\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.1.22",
3
+ "version": "2.1.24",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -10,12 +10,6 @@
10
10
  "types": "./dist/index.d.ts"
11
11
  }
12
12
  },
13
- "scripts": {
14
- "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
15
- "dev": "tsup src/index.ts --format esm --dts --watch",
16
- "prebuild": "node scripts/generate-templates.js",
17
- "typecheck": "tsc --noEmit"
18
- },
19
13
  "dependencies": {
20
14
  "kofi-stack-types": "^2.2.0",
21
15
  "handlebars": "^4.7.8",
@@ -25,5 +19,11 @@
25
19
  "@types/node": "^20.0.0",
26
20
  "tsup": "^8.0.0",
27
21
  "typescript": "^5.0.0"
22
+ },
23
+ "scripts": {
24
+ "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
25
+ "dev": "tsup src/index.ts --format esm --dts --watch",
26
+ "prebuild": "node scripts/generate-templates.js",
27
+ "typecheck": "tsc --noEmit"
28
28
  }
29
- }
29
+ }
@@ -1,6 +1,6 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-15T03:03:22.347Z
3
+ // Generated: 2026-01-15T03:23:42.699Z
4
4
  // Template count: 90
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {
@@ -28,7 +28,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
28
28
  "marketing/payload/next.config.ts.hbs": "import { withPayload } from '@payloadcms/next/withPayload'\nimport type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default withPayload(nextConfig)\n",
29
29
  "marketing/payload/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev -p 3001\",\n \"build\": \"next build\",\n \"start\": \"next start\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"typecheck\": \"tsc --noEmit\",\n \"db:push\": \"payload migrate\",\n \"db:seed\": \"tsx src/seed.ts\"\n },\n \"dependencies\": {\n \"next\": \"^15.4.10\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"payload\": \"^3.70.0\",\n \"@payloadcms/db-postgres\": \"^3.0.0\",\n \"@payloadcms/next\": \"^3.0.0\",\n \"@payloadcms/richtext-lexical\": \"^3.0.0\",\n \"@payloadcms/email-resend\": \"^3.0.0\",\n \"@payloadcms/plugin-seo\": \"^3.0.0\",\n{{#if (eq integrations.payloadStorage 's3')}}\n \"@payloadcms/storage-s3\": \"^3.0.0\",\n{{/if}}\n{{#if (eq integrations.payloadStorage 'r2')}}\n \"@payloadcms/storage-s3\": \"^3.0.0\",\n{{/if}}\n{{#if (eq integrations.payloadStorage 'vercel-blob')}}\n \"@payloadcms/storage-vercel-blob\": \"^3.0.0\",\n{{/if}}\n{{#if (eq integrations.payloadStorage 'gcs')}}\n \"@payloadcms/storage-gcs\": \"^3.0.0\",\n{{/if}}\n \"sharp\": \"^0.33.0\",\n \"@repo/ui\": \"workspace:*\"\n },\n \"devDependencies\": {\n \"@repo/config-typescript\": \"workspace:*\",\n \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"postcss\": \"^8.4.0\",\n \"sass\": \"^1.86.0\",\n \"typescript\": \"^5.0.0\",\n \"tsx\": \"^4.0.0\"\n }\n}\n",
30
30
  "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
31
- "marketing/payload/src/app/(frontend)/layout.tsx.hbs": "export default function FrontendLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return <>{children}</>\n}\n",
31
+ "marketing/payload/src/app/(frontend)/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport '../globals.css'\n\nexport const metadata: Metadata = {\n title: '{{projectName}} - Marketing',\n description: 'Built with Payload CMS and Next.js',\n}\n\nexport default function FrontendLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n",
32
32
  "marketing/payload/src/app/(frontend)/page.tsx.hbs": "import { getPayload } from 'payload'\nimport config from '@/payload.config'\n\nexport default async function HomePage() {\n // Check if DATABASE_URL is configured\n if (!process.env.DATABASE_URL || process.env.DATABASE_URL.includes('[PASSWORD]')) {\n return (\n <main className=\"min-h-screen bg-gradient-to-b from-gray-50 to-white\">\n <div className=\"container mx-auto px-4 py-16\">\n <div className=\"max-w-2xl mx-auto text-center\">\n <h1 className=\"text-4xl font-bold text-gray-900 mb-4\">\n Welcome to Your Marketing Site\n </h1>\n <p className=\"text-lg text-gray-600 mb-8\">\n Built with Payload CMS and Next.js\n </p>\n <div className=\"bg-amber-50 border border-amber-200 rounded-lg p-6 text-left\">\n <h2 className=\"text-lg font-semibold text-amber-800 mb-2\">\n Database Setup Required\n </h2>\n <p className=\"text-amber-700 mb-4\">\n To get started, configure your PostgreSQL database:\n </p>\n <ol className=\"list-decimal list-inside text-amber-700 space-y-2\">\n <li>Create a Supabase project at <a href=\"https://supabase.com\" className=\"underline\" target=\"_blank\" rel=\"noopener noreferrer\">supabase.com</a></li>\n <li>Copy your database connection string</li>\n <li>Update <code className=\"bg-amber-100 px-1 rounded\">DATABASE_URL</code> in <code className=\"bg-amber-100 px-1 rounded\">apps/marketing/.env.local</code></li>\n <li>Restart the development server</li>\n </ol>\n </div>\n <div className=\"mt-8\">\n <a\n href=\"/admin\"\n className=\"inline-flex items-center px-6 py-3 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors\"\n >\n Go to Admin Panel\n </a>\n </div>\n </div>\n </div>\n </main>\n )\n }\n\n try {\n const payload = await getPayload({ config })\n\n const settings = await payload.findGlobal({\n slug: 'site-settings',\n })\n\n return (\n <main className=\"min-h-screen\">\n <div className=\"container mx-auto px-4 py-16\">\n <h1 className=\"text-4xl font-bold\">{settings.siteName || 'Marketing Site'}</h1>\n <p className=\"mt-4 text-lg text-gray-600\">{settings.siteDescription || 'Built with Payload CMS'}</p>\n </div>\n </main>\n )\n } catch (error) {\n return (\n <main className=\"min-h-screen bg-gradient-to-b from-red-50 to-white\">\n <div className=\"container mx-auto px-4 py-16\">\n <div className=\"max-w-2xl mx-auto text-center\">\n <h1 className=\"text-4xl font-bold text-gray-900 mb-4\">\n Database Connection Error\n </h1>\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-6 text-left\">\n <p className=\"text-red-700 mb-4\">\n Could not connect to the database. Please check your configuration:\n </p>\n <ul className=\"list-disc list-inside text-red-700 space-y-2\">\n <li>Verify <code className=\"bg-red-100 px-1 rounded\">DATABASE_URL</code> is correct</li>\n <li>Ensure your database is running and accessible</li>\n <li>Check that the database credentials are valid</li>\n </ul>\n </div>\n </div>\n </div>\n </main>\n )\n }\n}\n",
33
33
  "marketing/payload/src/app/(payload)/admin/[[...segments]]/not-found.tsx.hbs": "import config from '@/payload.config'\nimport { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'\nimport { importMap } from '../../importMap.js'\nimport type { Metadata } from 'next'\n\ntype Args = {\n params: Promise<{ segments: string[] }>\n searchParams: Promise<Record<string, string | string[]>>\n}\n\nexport const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>\n generatePageMetadata({ config, params, searchParams })\n\nconst NotFound = ({ params, searchParams }: Args) =>\n NotFoundPage({ config, importMap, params, searchParams })\n\nexport default NotFound\n",
34
34
  "marketing/payload/src/app/(payload)/admin/[[...segments]]/page.tsx.hbs": "import config from '@/payload.config'\nimport { RootPage, generatePageMetadata } from '@payloadcms/next/views'\nimport { importMap } from '../../importMap.js'\nimport type { Metadata } from 'next'\n\ntype Args = {\n params: Promise<{ segments: string[] }>\n searchParams: Promise<Record<string, string | string[]>>\n}\n\nexport const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>\n generatePageMetadata({ config, params, searchParams })\n\nconst Page = ({ params, searchParams }: Args) =>\n RootPage({ config, importMap, params, searchParams })\n\nexport default Page\n",
@@ -39,7 +39,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
39
39
  "marketing/payload/src/app/(payload)/importMap.js.hbs": "export const importMap = {}\n",
40
40
  "marketing/payload/src/app/(payload)/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport config from '@/payload.config'\nimport { RootLayout, handleServerFunctions } from '@payloadcms/next/layouts'\nimport type { ServerFunctionClient } from 'payload'\nimport { importMap } from './importMap.js'\nimport './custom.scss'\n\nexport const metadata: Metadata = {\n title: 'Admin Panel',\n}\n\ntype LayoutArgs = {\n children: React.ReactNode\n}\n\nconst serverFunction: ServerFunctionClient = async function (args) {\n 'use server'\n return handleServerFunctions({ ...args, config, importMap })\n}\n\nconst Layout = ({ children }: LayoutArgs) =>\n RootLayout({ children, config, importMap, serverFunction })\n\nexport default Layout\n",
41
41
  "marketing/payload/src/app/globals.css.hbs": "@import \"tailwindcss\";\n\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --font-sans: var(--font-geist-sans);\n --font-mono: var(--font-geist-mono);\n --color-ring: var(--ring);\n --color-input: var(--input);\n --color-border: var(--border);\n --color-destructive: var(--destructive);\n --color-accent-foreground: var(--accent-foreground);\n --color-accent: var(--accent);\n --color-muted-foreground: var(--muted-foreground);\n --color-muted: var(--muted);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-secondary: var(--secondary);\n --color-primary-foreground: var(--primary-foreground);\n --color-primary: var(--primary);\n --color-popover-foreground: var(--popover-foreground);\n --color-popover: var(--popover);\n --color-card-foreground: var(--card-foreground);\n --color-card: var(--card);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n:root {\n --radius: 0.625rem;\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n\n body {\n @apply bg-background text-foreground;\n }\n}\n",
42
- "marketing/payload/src/app/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport './globals.css'\n\nexport const metadata: Metadata = {\n title: 'Marketing Site',\n description: 'Built with Payload CMS',\n}\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n",
42
+ "marketing/payload/src/app/layout.tsx.hbs": "// Root layout is minimal - each route group has its own complete layout\n// This prevents nested <html>/<body> tags between frontend and Payload admin\n// CSS is imported in each route group's layout to avoid style conflicts\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return children\n}\n",
43
43
  "marketing/payload/src/blocks/Benefits.ts.hbs": "import type { Block } from 'payload'\n\nexport const BenefitsBlock: Block = {\n slug: 'benefits',\n labels: { singular: 'Benefits', plural: 'Benefits' },\n fields: [\n { name: 'label', type: 'text' },\n { name: 'heading', type: 'text', required: true },\n { name: 'description', type: 'textarea' },\n { name: 'image', type: 'upload', relationTo: 'media' },\n {\n name: 'imagePosition',\n type: 'select',\n options: [\n { label: 'Left', value: 'left' },\n { label: 'Right', value: 'right' },\n ],\n defaultValue: 'right',\n },\n {\n name: 'benefits',\n type: 'array',\n fields: [{ name: 'text', type: 'text', required: true }],\n },\n {\n name: 'cta',\n type: 'group',\n fields: [\n { name: 'label', type: 'text' },\n { name: 'url', type: 'text' },\n ],\n },\n ],\n}\n",
44
44
  "marketing/payload/src/blocks/CTA.ts.hbs": "import type { Block } from 'payload'\n\nexport const CTABlock: Block = {\n slug: 'cta',\n labels: { singular: 'CTA', plural: 'CTAs' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'description', type: 'textarea' },\n {\n name: 'style',\n type: 'select',\n options: [\n { label: 'Light', value: 'light' },\n { label: 'Dark', value: 'dark' },\n { label: 'Primary', value: 'primary' },\n ],\n defaultValue: 'dark',\n },\n {\n name: 'buttons',\n type: 'array',\n maxRows: 2,\n fields: [\n { name: 'label', type: 'text', required: true },\n { name: 'url', type: 'text', required: true },\n {\n name: 'variant',\n type: 'select',\n options: [\n { label: 'Primary', value: 'primary' },\n { label: 'Secondary', value: 'secondary' },\n { label: 'Outline', value: 'outline' },\n ],\n defaultValue: 'primary',\n },\n ],\n },\n ],\n}\n",
45
45
  "marketing/payload/src/blocks/Content.ts.hbs": "import type { Block } from 'payload'\n\nexport const ContentBlock: Block = {\n slug: 'content',\n labels: { singular: 'Content', plural: 'Content' },\n fields: [\n { name: 'content', type: 'richText' },\n ],\n}\n",
@@ -1,7 +1,19 @@
1
+ import type { Metadata } from 'next'
2
+ import '../globals.css'
3
+
4
+ export const metadata: Metadata = {
5
+ title: '{{projectName}} - Marketing',
6
+ description: 'Built with Payload CMS and Next.js',
7
+ }
8
+
1
9
  export default function FrontendLayout({
2
10
  children,
3
11
  }: {
4
12
  children: React.ReactNode
5
13
  }) {
6
- return <>{children}</>
14
+ return (
15
+ <html lang="en">
16
+ <body>{children}</body>
17
+ </html>
18
+ )
7
19
  }
@@ -1,19 +1,10 @@
1
- import type { Metadata } from 'next'
2
- import './globals.css'
3
-
4
- export const metadata: Metadata = {
5
- title: 'Marketing Site',
6
- description: 'Built with Payload CMS',
7
- }
8
-
1
+ // Root layout is minimal - each route group has its own complete layout
2
+ // This prevents nested <html>/<body> tags between frontend and Payload admin
3
+ // CSS is imported in each route group's layout to avoid style conflicts
9
4
  export default function RootLayout({
10
5
  children,
11
6
  }: {
12
7
  children: React.ReactNode
13
8
  }) {
14
- return (
15
- <html lang="en">
16
- <body>{children}</body>
17
- </html>
18
- )
9
+ return children
19
10
  }