kofi-stack-template-generator 2.0.11 → 2.0.13

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 (49) hide show
  1. package/.turbo/turbo-build.log +5 -5
  2. package/dist/index.js +274 -1
  3. package/package.json +1 -1
  4. package/src/templates.generated.ts +47 -3
  5. package/templates/marketing/nextjs/next.config.ts.hbs +7 -0
  6. package/templates/marketing/nextjs/package.json.hbs +29 -0
  7. package/templates/marketing/nextjs/postcss.config.mjs.hbs +5 -0
  8. package/templates/marketing/nextjs/src/app/globals.css.hbs +18 -0
  9. package/templates/marketing/nextjs/src/app/layout.tsx.hbs +32 -0
  10. package/templates/marketing/nextjs/src/app/page.tsx.hbs +127 -0
  11. package/templates/marketing/nextjs/tsconfig.json.hbs +23 -0
  12. package/templates/marketing/payload/_env.example.hbs +18 -0
  13. package/templates/marketing/payload/_env.local.hbs +18 -0
  14. package/templates/marketing/payload/next.config.ts.hbs +11 -0
  15. package/templates/marketing/payload/package.json.hbs +39 -0
  16. package/templates/marketing/payload/postcss.config.mjs.hbs +5 -0
  17. package/templates/marketing/payload/src/app/(frontend)/layout.tsx.hbs +7 -0
  18. package/templates/marketing/payload/src/app/(frontend)/page.tsx.hbs +83 -0
  19. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/not-found.tsx.hbs +17 -0
  20. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/page.tsx.hbs +17 -0
  21. package/templates/marketing/payload/src/app/(payload)/api/[...slug]/route.ts.hbs +9 -0
  22. package/templates/marketing/payload/src/app/(payload)/api/graphql/route.ts.hbs +5 -0
  23. package/templates/marketing/payload/src/app/(payload)/api/graphql-playground/route.ts.hbs +5 -0
  24. package/templates/marketing/payload/src/app/(payload)/custom.scss.hbs +1 -0
  25. package/templates/marketing/payload/src/app/(payload)/importMap.js.hbs +1 -0
  26. package/templates/marketing/payload/src/app/(payload)/layout.tsx.hbs +18 -0
  27. package/templates/marketing/payload/src/app/globals.css.hbs +11 -0
  28. package/templates/marketing/payload/src/app/layout.tsx.hbs +19 -0
  29. package/templates/marketing/payload/src/blocks/Benefits.ts.hbs +34 -0
  30. package/templates/marketing/payload/src/blocks/CTA.ts.hbs +39 -0
  31. package/templates/marketing/payload/src/blocks/Content.ts.hbs +9 -0
  32. package/templates/marketing/payload/src/blocks/FAQ.ts.hbs +18 -0
  33. package/templates/marketing/payload/src/blocks/Features.ts.hbs +32 -0
  34. package/templates/marketing/payload/src/blocks/Hero.ts.hbs +40 -0
  35. package/templates/marketing/payload/src/blocks/LogoBanner.ts.hbs +17 -0
  36. package/templates/marketing/payload/src/blocks/Pricing.ts.hbs +37 -0
  37. package/templates/marketing/payload/src/blocks/Testimonials.ts.hbs +21 -0
  38. package/templates/marketing/payload/src/blocks/index.ts.hbs +9 -0
  39. package/templates/marketing/payload/src/collections/Media.ts.hbs +44 -0
  40. package/templates/marketing/payload/src/collections/Pages.ts.hbs +66 -0
  41. package/templates/marketing/payload/src/collections/Posts.ts.hbs +65 -0
  42. package/templates/marketing/payload/src/collections/Users.ts.hbs +25 -0
  43. package/templates/marketing/payload/src/collections/index.ts.hbs +4 -0
  44. package/templates/marketing/payload/src/globals/Navigation.ts.hbs +51 -0
  45. package/templates/marketing/payload/src/globals/SiteSettings.ts.hbs +49 -0
  46. package/templates/marketing/payload/src/globals/index.ts.hbs +2 -0
  47. package/templates/marketing/payload/src/payload.config.ts.hbs +61 -0
  48. package/templates/marketing/payload/tsconfig.json.hbs +23 -0
  49. package/templates/monorepo/turbo.json.hbs +3 -0
@@ -1,20 +1,20 @@
1
1
 
2
- > kofi-stack-template-generator@2.0.11 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
2
+ > kofi-stack-template-generator@2.0.13 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
3
3
  > pnpm run prebuild && tsup src/index.ts --format esm --dts
4
4
 
5
5
 
6
- > kofi-stack-template-generator@2.0.11 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
6
+ > kofi-stack-template-generator@2.0.13 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
7
7
  > node scripts/generate-templates.js
8
8
 
9
9
  Generating templates.generated.ts...
10
- Generated templates.generated.ts with 34 templates
10
+ Generated templates.generated.ts with 78 templates
11
11
  CLI Building entry: src/index.ts
12
12
  CLI Using tsconfig: tsconfig.json
13
13
  CLI tsup v8.5.1
14
14
  CLI Target: es2022
15
15
  ESM Build start
16
- ESM dist/index.js 40.14 KB
16
+ ESM dist/index.js 75.38 KB
17
17
  ESM ⚡️ Build success in 15ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 456ms
19
+ DTS ⚡️ Build success in 439ms
20
20
  DTS dist/index.d.ts 2.96 KB
package/dist/index.js CHANGED
@@ -292,9 +292,282 @@ var EMBEDDED_TEMPLATES = {
292
292
  }{{/if}}
293
293
  `,
294
294
  "integrations/posthog/src/components/providers/posthog-provider.tsx.hbs": "'use client'\n\nimport posthog from 'posthog-js'\nimport { PostHogProvider as PHProvider } from 'posthog-js/react'\nimport { useEffect } from 'react'\n\nexport function PostHogProvider({ children }: { children: React.ReactNode }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',\n person_profiles: 'identified_only',\n capture_pageview: false, // We capture pageviews manually\n })\n }, [])\n\n return <PHProvider client={posthog}>{children}</PHProvider>\n}\n",
295
+ "marketing/nextjs/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default nextConfig\n",
296
+ "marketing/nextjs/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "next dev --turbopack -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 },\n "dependencies": {\n "next": "^16.0.0",\n "react": "^19.0.0",\n "react-dom": "^19.0.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 "typescript": "^5.0.0"\n }\n}\n',
297
+ "marketing/nextjs/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
298
+ "marketing/nextjs/src/app/globals.css.hbs": '@import "tailwindcss";\n\n:root {\n --background: #ffffff;\n --foreground: #171717;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #0a0a0a;\n --foreground: #ededed;\n }\n}\n\nbody {\n color: var(--foreground);\n background: var(--background);\n}\n',
299
+ "marketing/nextjs/src/app/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport { Geist, Geist_Mono } from 'next/font/google'\nimport './globals.css'\n\nconst geistSans = Geist({\n variable: '--font-geist-sans',\n subsets: ['latin'],\n})\n\nconst geistMono = Geist_Mono({\n variable: '--font-geist-mono',\n subsets: ['latin'],\n})\n\nexport const metadata: Metadata = {\n title: '{{projectName}} - Marketing',\n description: 'Marketing site for {{projectName}}',\n}\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <html lang=\"en\">\n <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>\n {children}\n </body>\n </html>\n )\n}\n",
300
+ "marketing/nextjs/src/app/page.tsx.hbs": `export default function HomePage() {
301
+ return (
302
+ <main className="min-h-screen">
303
+ {/* Hero Section */}
304
+ <section className="relative overflow-hidden bg-gradient-to-b from-gray-50 to-white dark:from-gray-900 dark:to-gray-800">
305
+ <div className="container mx-auto px-4 py-24 sm:py-32">
306
+ <div className="text-center">
307
+ <h1 className="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl">
308
+ Welcome to {{projectName}}
309
+ </h1>
310
+ <p className="mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
311
+ A modern full-stack application built with Next.js, Convex, and Better-Auth.
312
+ </p>
313
+ <div className="mt-10 flex items-center justify-center gap-x-6">
314
+ <a
315
+ href="/app"
316
+ className="rounded-lg bg-gray-900 dark:bg-white px-6 py-3 text-sm font-semibold text-white dark:text-gray-900 shadow-sm hover:opacity-90 transition-opacity"
317
+ >
318
+ Get Started
319
+ </a>
320
+ <a
321
+ href="#features"
322
+ className="text-sm font-semibold leading-6 text-gray-900 dark:text-white"
323
+ >
324
+ Learn more <span aria-hidden="true">\u2192</span>
325
+ </a>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ </section>
330
+
331
+ {/* Features Section */}
332
+ <section id="features" className="py-24 sm:py-32">
333
+ <div className="container mx-auto px-4">
334
+ <div className="text-center mb-16">
335
+ <h2 className="text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl">
336
+ Everything you need
337
+ </h2>
338
+ <p className="mt-4 text-lg text-gray-600 dark:text-gray-300">
339
+ Built with the best tools for modern web development
340
+ </p>
341
+ </div>
342
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
343
+ <div className="p-6 rounded-xl border border-gray-200 dark:border-gray-700">
344
+ <div className="w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4">
345
+ <svg className="w-6 h-6 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
346
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
347
+ </svg>
348
+ </div>
349
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
350
+ Lightning Fast
351
+ </h3>
352
+ <p className="text-gray-600 dark:text-gray-300">
353
+ Built on Next.js with Turbopack for instant hot reload and optimized production builds.
354
+ </p>
355
+ </div>
356
+ <div className="p-6 rounded-xl border border-gray-200 dark:border-gray-700">
357
+ <div className="w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4">
358
+ <svg className="w-6 h-6 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
359
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4" />
360
+ </svg>
361
+ </div>
362
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
363
+ Real-time Database
364
+ </h3>
365
+ <p className="text-gray-600 dark:text-gray-300">
366
+ Powered by Convex for automatic real-time sync and type-safe queries.
367
+ </p>
368
+ </div>
369
+ <div className="p-6 rounded-xl border border-gray-200 dark:border-gray-700">
370
+ <div className="w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4">
371
+ <svg className="w-6 h-6 text-gray-900 dark:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
372
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
373
+ </svg>
374
+ </div>
375
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
376
+ Secure Auth
377
+ </h3>
378
+ <p className="text-gray-600 dark:text-gray-300">
379
+ Better-Auth provides secure, flexible authentication with social login support.
380
+ </p>
381
+ </div>
382
+ </div>
383
+ </div>
384
+ </section>
385
+
386
+ {/* CTA Section */}
387
+ <section className="py-24 sm:py-32 bg-gray-900 dark:bg-gray-800">
388
+ <div className="container mx-auto px-4 text-center">
389
+ <h2 className="text-3xl font-bold tracking-tight text-white sm:text-4xl">
390
+ Ready to get started?
391
+ </h2>
392
+ <p className="mt-4 text-lg text-gray-300 max-w-2xl mx-auto">
393
+ Start building your next project with our full-stack template.
394
+ </p>
395
+ <div className="mt-10">
396
+ <a
397
+ href="/app"
398
+ className="rounded-lg bg-white px-6 py-3 text-sm font-semibold text-gray-900 shadow-sm hover:opacity-90 transition-opacity"
399
+ >
400
+ Launch App
401
+ </a>
402
+ </div>
403
+ </div>
404
+ </section>
405
+
406
+ {/* Footer */}
407
+ <footer className="border-t border-gray-200 dark:border-gray-700">
408
+ <div className="container mx-auto px-4 py-12">
409
+ <div className="text-center text-gray-600 dark:text-gray-300">
410
+ <p>
411
+ Built with{' '}
412
+ <a
413
+ href="https://github.com/theodenanyoh11/create-kofi-stack"
414
+ className="text-gray-900 dark:text-white hover:underline"
415
+ target="_blank"
416
+ rel="noopener noreferrer"
417
+ >
418
+ create-kofi-stack
419
+ </a>
420
+ </p>
421
+ </div>
422
+ </div>
423
+ </footer>
424
+ </main>
425
+ )
426
+ }
427
+ `,
428
+ "marketing/nextjs/tsconfig.json.hbs": '{\n "compilerOptions": {\n "target": "ES2017",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "jsx": "react-jsx",\n "incremental": true,\n "plugins": [{ "name": "next" }],\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],\n "exclude": ["node_modules"]\n}\n',
429
+ "marketing/payload/_env.example.hbs": '# Database (Supabase PostgreSQL)\nDATABASE_URL="postgresql://postgres:[PASSWORD]@db.[PROJECT].supabase.co:5432/postgres"\n\n# Payload CMS\nPAYLOAD_SECRET="" # Generate with: openssl rand -base64 32\n\n# Scheduled Jobs\nCRON_SECRET="" # Generate with: openssl rand -base64 32\n\n# Draft Previews\nPREVIEW_SECRET="" # Generate with: openssl rand -base64 32\n\n# S3 Storage (Supabase Storage)\nS3_BUCKET="media"\nS3_ACCESS_KEY_ID=""\nS3_SECRET_ACCESS_KEY=""\nS3_REGION="auto"\nS3_ENDPOINT="https://[PROJECT].supabase.co/storage/v1/s3"\n',
430
+ "marketing/payload/_env.local.hbs": '# Database (Supabase PostgreSQL)\nDATABASE_URL="postgresql://postgres:[PASSWORD]@db.[PROJECT].supabase.co:5432/postgres"\n\n# Payload CMS\nPAYLOAD_SECRET="" # Generate with: openssl rand -base64 32\n\n# Scheduled Jobs\nCRON_SECRET="" # Generate with: openssl rand -base64 32\n\n# Draft Previews\nPREVIEW_SECRET="" # Generate with: openssl rand -base64 32\n\n# S3 Storage (Supabase Storage)\nS3_BUCKET="media"\nS3_ACCESS_KEY_ID=""\nS3_SECRET_ACCESS_KEY=""\nS3_REGION="auto"\nS3_ENDPOINT="https://[PROJECT].supabase.co/storage/v1/s3"\n',
431
+ "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 experimental: {\n turbo: {},\n },\n}\n\nexport default withPayload(nextConfig)\n",
432
+ "marketing/payload/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "next dev --turbopack -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/storage-s3": "^3.0.0",\n "@payloadcms/plugin-seo": "^3.0.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',
433
+ "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
434
+ "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",
435
+ "marketing/payload/src/app/(frontend)/page.tsx.hbs": `import { getPayload } from 'payload'
436
+ import config from '@/payload.config'
437
+
438
+ export default async function HomePage() {
439
+ // Check if DATABASE_URL is configured
440
+ if (!process.env.DATABASE_URL || process.env.DATABASE_URL.includes('[PASSWORD]')) {
441
+ return (
442
+ <main className="min-h-screen bg-gradient-to-b from-gray-50 to-white">
443
+ <div className="container mx-auto px-4 py-16">
444
+ <div className="max-w-2xl mx-auto text-center">
445
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">
446
+ Welcome to Your Marketing Site
447
+ </h1>
448
+ <p className="text-lg text-gray-600 mb-8">
449
+ Built with Payload CMS and Next.js
450
+ </p>
451
+ <div className="bg-amber-50 border border-amber-200 rounded-lg p-6 text-left">
452
+ <h2 className="text-lg font-semibold text-amber-800 mb-2">
453
+ Database Setup Required
454
+ </h2>
455
+ <p className="text-amber-700 mb-4">
456
+ To get started, configure your PostgreSQL database:
457
+ </p>
458
+ <ol className="list-decimal list-inside text-amber-700 space-y-2">
459
+ <li>Create a Supabase project at <a href="https://supabase.com" className="underline" target="_blank" rel="noopener noreferrer">supabase.com</a></li>
460
+ <li>Copy your database connection string</li>
461
+ <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>
462
+ <li>Restart the development server</li>
463
+ </ol>
464
+ </div>
465
+ <div className="mt-8">
466
+ <a
467
+ href="/admin"
468
+ className="inline-flex items-center px-6 py-3 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors"
469
+ >
470
+ Go to Admin Panel
471
+ </a>
472
+ </div>
473
+ </div>
474
+ </div>
475
+ </main>
476
+ )
477
+ }
478
+
479
+ try {
480
+ const payload = await getPayload({ config })
481
+
482
+ const settings = await payload.findGlobal({
483
+ slug: 'site-settings',
484
+ })
485
+
486
+ return (
487
+ <main className="min-h-screen">
488
+ <div className="container mx-auto px-4 py-16">
489
+ <h1 className="text-4xl font-bold">{settings.siteName || 'Marketing Site'}</h1>
490
+ <p className="mt-4 text-lg text-gray-600">{settings.siteDescription || 'Built with Payload CMS'}</p>
491
+ </div>
492
+ </main>
493
+ )
494
+ } catch (error) {
495
+ return (
496
+ <main className="min-h-screen bg-gradient-to-b from-red-50 to-white">
497
+ <div className="container mx-auto px-4 py-16">
498
+ <div className="max-w-2xl mx-auto text-center">
499
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">
500
+ Database Connection Error
501
+ </h1>
502
+ <div className="bg-red-50 border border-red-200 rounded-lg p-6 text-left">
503
+ <p className="text-red-700 mb-4">
504
+ Could not connect to the database. Please check your configuration:
505
+ </p>
506
+ <ul className="list-disc list-inside text-red-700 space-y-2">
507
+ <li>Verify <code className="bg-red-100 px-1 rounded">DATABASE_URL</code> is correct</li>
508
+ <li>Ensure your database is running and accessible</li>
509
+ <li>Check that the database credentials are valid</li>
510
+ </ul>
511
+ </div>
512
+ </div>
513
+ </div>
514
+ </main>
515
+ )
516
+ }
517
+ }
518
+ `,
519
+ "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",
520
+ "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",
521
+ "marketing/payload/src/app/(payload)/api/[...slug]/route.ts.hbs": "import config from '@/payload.config'\nimport { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const GET = REST_GET(config, importMap)\nexport const POST = REST_POST(config, importMap)\nexport const DELETE = REST_DELETE(config, importMap)\nexport const PATCH = REST_PATCH(config, importMap)\nexport const OPTIONS = REST_OPTIONS(config)\n",
522
+ "marketing/payload/src/app/(payload)/api/graphql/route.ts.hbs": "import config from '@/payload.config'\nimport { GRAPHQL_POST } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const POST = GRAPHQL_POST(config, importMap)\n",
523
+ "marketing/payload/src/app/(payload)/api/graphql-playground/route.ts.hbs": "import config from '@/payload.config'\nimport { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const GET = GRAPHQL_PLAYGROUND_GET(config, importMap)\n",
524
+ "marketing/payload/src/app/(payload)/custom.scss.hbs": "/* Custom Payload admin styles */\n",
525
+ "marketing/payload/src/app/(payload)/importMap.js.hbs": "export const importMap = {}\n",
526
+ "marketing/payload/src/app/(payload)/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport config from '@/payload.config'\nimport { RootLayout } from '@payloadcms/next/layouts'\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 Layout = ({ children }: LayoutArgs) =>\n RootLayout({ children, config, importMap })\n\nexport default Layout\n",
527
+ "marketing/payload/src/app/globals.css.hbs": '@import "tailwindcss";\n\n@layer base {\n * {\n @apply border-border;\n }\n\n body {\n @apply bg-background text-foreground;\n }\n}\n',
528
+ "marketing/payload/src/app/layout.tsx.hbs": `import type { Metadata } from 'next'
529
+ import './globals.css'
530
+
531
+ export const metadata: Metadata = {
532
+ title: 'Marketing Site',
533
+ description: 'Built with Payload CMS',
534
+ }
535
+
536
+ export default function RootLayout({
537
+ children,
538
+ }: {
539
+ children: React.ReactNode
540
+ }) {
541
+ return (
542
+ <html lang="en">
543
+ <body>{children}</body>
544
+ </html>
545
+ )
546
+ }
547
+ `,
548
+ "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",
549
+ "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",
550
+ "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",
551
+ "marketing/payload/src/blocks/FAQ.ts.hbs": "import type { Block } from 'payload'\n\nexport const FAQBlock: Block = {\n slug: 'faq',\n labels: { singular: 'FAQ', plural: 'FAQs' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'items',\n type: 'array',\n fields: [\n { name: 'question', type: 'text', required: true },\n { name: 'answer', type: 'textarea', required: true },\n ],\n },\n ],\n}\n",
552
+ "marketing/payload/src/blocks/Features.ts.hbs": "import type { Block } from 'payload'\n\nexport const FeaturesBlock: Block = {\n slug: 'features',\n labels: { singular: 'Features', plural: 'Features' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'features',\n type: 'array',\n fields: [\n {\n name: 'icon',\n type: 'select',\n options: [\n { label: 'Zap', value: 'zap' },\n { label: 'Shield', value: 'shield' },\n { label: 'Globe', value: 'globe' },\n { label: 'Layers', value: 'layers' },\n { label: 'Settings', value: 'settings' },\n { label: 'Users', value: 'users' },\n { label: 'Lock', value: 'lock' },\n { label: 'Star', value: 'star' },\n ],\n },\n { name: 'title', type: 'text', required: true },\n { name: 'description', type: 'textarea' },\n ],\n },\n ],\n}\n",
553
+ "marketing/payload/src/blocks/Hero.ts.hbs": "import type { Block } from 'payload'\n\nexport const HeroBlock: Block = {\n slug: 'hero',\n labels: { singular: 'Hero', plural: 'Heroes' },\n fields: [\n {\n name: 'heading',\n type: 'text',\n required: true,\n },\n {\n name: 'subheading',\n type: 'textarea',\n },\n {\n name: 'image',\n type: 'upload',\n relationTo: 'media',\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 ],\n defaultValue: 'primary',\n },\n ],\n },\n ],\n}\n",
554
+ "marketing/payload/src/blocks/LogoBanner.ts.hbs": "import type { Block } from 'payload'\n\nexport const LogoBannerBlock: Block = {\n slug: 'logoBanner',\n labels: { singular: 'Logo Banner', plural: 'Logo Banners' },\n fields: [\n { name: 'heading', type: 'text' },\n {\n name: 'logos',\n type: 'array',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'logo', type: 'upload', relationTo: 'media' },\n ],\n },\n ],\n}\n",
555
+ "marketing/payload/src/blocks/Pricing.ts.hbs": "import type { Block } from 'payload'\n\nexport const PricingBlock: Block = {\n slug: 'pricing',\n labels: { singular: 'Pricing', plural: 'Pricing' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'plans',\n type: 'array',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'price', type: 'text', required: true },\n { name: 'period', type: 'text', defaultValue: '/month' },\n { name: 'description', type: 'textarea' },\n { name: 'featured', type: 'checkbox', defaultValue: false },\n {\n name: 'features',\n type: 'array',\n fields: [\n { name: 'feature', type: 'text', required: true },\n { name: 'included', type: 'checkbox', defaultValue: true },\n ],\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 ],\n}\n",
556
+ "marketing/payload/src/blocks/Testimonials.ts.hbs": "import type { Block } from 'payload'\n\nexport const TestimonialsBlock: Block = {\n slug: 'testimonials',\n labels: { singular: 'Testimonials', plural: 'Testimonials' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'testimonials',\n type: 'array',\n fields: [\n { name: 'quote', type: 'textarea', required: true },\n { name: 'author', type: 'text', required: true },\n { name: 'role', type: 'text' },\n { name: 'company', type: 'text' },\n { name: 'image', type: 'upload', relationTo: 'media' },\n ],\n },\n ],\n}\n",
557
+ "marketing/payload/src/blocks/index.ts.hbs": "export { HeroBlock } from './Hero'\nexport { LogoBannerBlock } from './LogoBanner'\nexport { FeaturesBlock } from './Features'\nexport { BenefitsBlock } from './Benefits'\nexport { PricingBlock } from './Pricing'\nexport { TestimonialsBlock } from './Testimonials'\nexport { FAQBlock } from './FAQ'\nexport { ContentBlock } from './Content'\nexport { CTABlock } from './CTA'\n",
558
+ "marketing/payload/src/collections/Media.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Media: CollectionConfig = {\n slug: 'media',\n access: {\n read: () => true,\n },\n upload: {\n staticDir: 'media',\n imageSizes: [\n {\n name: 'thumbnail',\n width: 400,\n height: 300,\n position: 'centre',\n },\n {\n name: 'card',\n width: 768,\n height: 432,\n position: 'centre',\n },\n {\n name: 'hero',\n width: 1920,\n height: 1080,\n position: 'centre',\n },\n ],\n adminThumbnail: 'thumbnail',\n mimeTypes: ['image/*'],\n },\n fields: [\n {\n name: 'alt',\n type: 'text',\n required: true,\n },\n {\n name: 'caption',\n type: 'text',\n },\n ],\n}\n",
559
+ "marketing/payload/src/collections/Pages.ts.hbs": "import type { CollectionConfig } from 'payload'\nimport {\n HeroBlock,\n LogoBannerBlock,\n FeaturesBlock,\n BenefitsBlock,\n PricingBlock,\n TestimonialsBlock,\n FAQBlock,\n ContentBlock,\n CTABlock,\n} from '../blocks'\n\nexport const Pages: CollectionConfig = {\n slug: 'pages',\n admin: {\n useAsTitle: 'title',\n defaultColumns: ['title', 'slug', 'status', 'updatedAt'],\n },\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n unique: true,\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Published', value: 'published' },\n ],\n defaultValue: 'draft',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n HeroBlock,\n LogoBannerBlock,\n FeaturesBlock,\n BenefitsBlock,\n PricingBlock,\n TestimonialsBlock,\n FAQBlock,\n ContentBlock,\n CTABlock,\n ],\n },\n ],\n}\n",
560
+ "marketing/payload/src/collections/Posts.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Posts: CollectionConfig = {\n slug: 'posts',\n admin: {\n useAsTitle: 'title',\n defaultColumns: ['title', 'author', 'status', 'publishedAt'],\n },\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n unique: true,\n },\n {\n name: 'excerpt',\n type: 'textarea',\n },\n {\n name: 'content',\n type: 'richText',\n },\n {\n name: 'featuredImage',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'author',\n type: 'relationship',\n relationTo: 'users',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Published', value: 'published' },\n ],\n defaultValue: 'draft',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'publishedAt',\n type: 'date',\n admin: {\n position: 'sidebar',\n },\n },\n ],\n}\n",
561
+ "marketing/payload/src/collections/Users.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Users: CollectionConfig = {\n slug: 'users',\n admin: {\n useAsTitle: 'email',\n },\n auth: true,\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n {\n name: 'role',\n type: 'select',\n options: [\n { label: 'Admin', value: 'admin' },\n { label: 'Editor', value: 'editor' },\n ],\n defaultValue: 'editor',\n required: true,\n },\n ],\n}\n",
562
+ "marketing/payload/src/collections/index.ts.hbs": "export { Users } from './Users'\nexport { Media } from './Media'\nexport { Pages } from './Pages'\nexport { Posts } from './Posts'\n",
563
+ "marketing/payload/src/globals/Navigation.ts.hbs": "import type { GlobalConfig } from 'payload'\n\nexport const Navigation: GlobalConfig = {\n slug: 'navigation',\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'label',\n type: 'text',\n required: true,\n },\n {\n name: 'link',\n type: 'group',\n fields: [\n {\n name: 'type',\n type: 'radio',\n options: [\n { label: 'Internal', value: 'internal' },\n { label: 'External', value: 'external' },\n ],\n defaultValue: 'internal',\n },\n {\n name: 'page',\n type: 'relationship',\n relationTo: 'pages',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'internal',\n },\n },\n {\n name: 'url',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'external',\n },\n },\n ],\n },\n ],\n },\n ],\n}\n",
564
+ "marketing/payload/src/globals/SiteSettings.ts.hbs": "import type { GlobalConfig } from 'payload'\n\nexport const SiteSettings: GlobalConfig = {\n slug: 'site-settings',\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'siteName',\n type: 'text',\n required: true,\n },\n {\n name: 'siteDescription',\n type: 'textarea',\n },\n {\n name: 'logo',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'favicon',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'socialLinks',\n type: 'array',\n fields: [\n {\n name: 'platform',\n type: 'select',\n options: [\n { label: 'Twitter', value: 'twitter' },\n { label: 'GitHub', value: 'github' },\n { label: 'LinkedIn', value: 'linkedin' },\n { label: 'Discord', value: 'discord' },\n ],\n },\n {\n name: 'url',\n type: 'text',\n },\n ],\n },\n ],\n}\n",
565
+ "marketing/payload/src/globals/index.ts.hbs": "export { SiteSettings } from './SiteSettings'\nexport { Navigation } from './Navigation'\n",
566
+ "marketing/payload/src/payload.config.ts.hbs": "import path from 'path'\nimport { fileURLToPath } from 'url'\nimport { buildConfig } from 'payload'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { s3Storage } from '@payloadcms/storage-s3'\nimport { seoPlugin } from '@payloadcms/plugin-seo'\n\nimport { Pages } from './collections/Pages'\nimport { Media } from './collections/Media'\nimport { Users } from './collections/Users'\nimport { Posts } from './collections/Posts'\nimport { SiteSettings } from './globals/SiteSettings'\nimport { Navigation } from './globals/Navigation'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nexport default buildConfig({\n admin: {\n user: Users.slug,\n importMap: {\n baseDir: path.resolve(__dirname),\n },\n },\n db: postgresAdapter({\n pool: {\n connectionString: process.env.DATABASE_URL,\n },\n }),\n editor: lexicalEditor(),\n collections: [Users, Media, Pages, Posts],\n globals: [SiteSettings, Navigation],\n plugins: [\n s3Storage({\n collections: {\n media: true,\n },\n bucket: process.env.S3_BUCKET!,\n config: {\n credentials: {\n accessKeyId: process.env.S3_ACCESS_KEY_ID!,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,\n },\n region: process.env.S3_REGION!,\n endpoint: process.env.S3_ENDPOINT!,\n forcePathStyle: true,\n },\n }),\n seoPlugin({\n collections: ['pages', 'posts'],\n uploadsCollection: 'media',\n generateTitle: ({ doc }) => `${doc?.title ?? ''} | {{projectName}}`,\n generateDescription: ({ doc }) => doc?.excerpt ?? '',\n }),\n ],\n secret: process.env.PAYLOAD_SECRET!,\n typescript: {\n outputFile: path.resolve(__dirname, 'payload-types.ts'),\n },\n})\n",
567
+ "marketing/payload/tsconfig.json.hbs": '{\n "compilerOptions": {\n "target": "ES2017",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "jsx": "react-jsx",\n "incremental": true,\n "plugins": [{ "name": "next" }],\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],\n "exclude": ["node_modules"]\n}\n',
295
568
  "monorepo/package.json.hbs": '{\n "name": "{{projectName}}",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "node scripts/dev.mjs",\n "dev:all": "turbo dev",\n "dev:web": "turbo -F @repo/web dev",\n "dev:backend": "turbo -F @repo/backend dev",\n "dev:setup": "turbo -F @repo/backend dev:setup",\n "build": "turbo build",\n "lint": "turbo lint",\n "lint:fix": "turbo lint:fix",\n "format": "turbo format",\n "typecheck": "turbo typecheck",\n "test": "turbo test",\n "test:e2e": "turbo test:e2e",\n "clean": "turbo clean && rm -rf node_modules",\n "prepare": "husky"\n },\n "devDependencies": {\n "turbo": "^2.0.0",\n "husky": "^9.0.0",\n "lint-staged": "^15.0.0"\n },\n "packageManager": "pnpm@9.0.0",\n "lint-staged": {\n "*.{js,ts,jsx,tsx}": ["biome check --apply"],\n "*.{json,md}": ["biome format --write"]\n }\n}\n',
296
569
  "monorepo/pnpm-workspace.yaml.hbs": 'packages:\n - "apps/*"\n - "packages/*"\n',
297
- "monorepo/turbo.json.hbs": '{\n "$schema": "https://turbo.build/schema.json",\n "ui": "tui",\n "tasks": {\n "build": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$", ".env*"],\n "outputs": [".next/**", "!.next/cache/**", "dist/**"]\n },\n "lint": {\n "dependsOn": ["^lint"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "lint:fix": {\n "dependsOn": ["^lint:fix"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "format": {\n "dependsOn": ["^format"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "typecheck": {\n "dependsOn": ["^typecheck"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "dev": {\n "cache": false,\n "persistent": true\n },\n "test": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "test:e2e": {\n "dependsOn": ["build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "clean": {\n "cache": false\n }\n }\n}\n',
570
+ "monorepo/turbo.json.hbs": '{\n "$schema": "https://turbo.build/schema.json",\n "ui": "tui",\n "tasks": {\n "build": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$", ".env*"],\n "outputs": [".next/**", "!.next/cache/**", "dist/**"]\n },\n "lint": {\n "dependsOn": ["^lint"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "lint:fix": {\n "dependsOn": ["^lint:fix"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "format": {\n "dependsOn": ["^format"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "typecheck": {\n "dependsOn": ["^typecheck"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "dev": {\n "cache": false,\n "persistent": true\n },\n "dev:setup": {\n "cache": false\n },\n "test": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "test:e2e": {\n "dependsOn": ["build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "clean": {\n "cache": false\n }\n }\n}\n',
298
571
  "packages/config-biome/biome.json.hbs": '{\n "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",\n "extends": ["../../biome.json"]\n}\n',
299
572
  "packages/config-biome/package.json.hbs": '{\n "name": "@repo/config-biome",\n "version": "0.1.0",\n "private": true,\n "files": ["biome.json"]\n}\n',
300
573
  "packages/config-typescript/base.json.hbs": '{\n "compilerOptions": {\n "target": "ES2020",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "incremental": true\n },\n "exclude": ["node_modules"]\n}\n',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-13T23:10:07.840Z
4
- // Template count: 34
3
+ // Generated: 2026-01-13T23:32:31.205Z
4
+ // Template count: 78
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {
7
7
  "base/_gitignore.hbs": "# Dependencies\nnode_modules\n.pnpm-store\n\n# Build outputs\n.next\ndist\n.turbo\nout\n\n# Testing\ncoverage\nplaywright-report\ntest-results\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea\n.vscode\n*.swp\n*.swo\n.DS_Store\n\n# Convex\n.convex\n\n# Vercel\n.vercel\n\n# Debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# TypeScript\n*.tsbuildinfo\n\n# Misc\n*.pem\n.cache\n",
@@ -14,9 +14,53 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
14
14
  "convex/package.json.hbs": "{{#if (eq structure 'monorepo')}}{\n \"name\": \"@repo/backend\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"main\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\"\n }\n },\n \"scripts\": {\n \"dev\": \"convex dev\",\n \"dev:setup\": \"convex dev --configure --until-success\",\n \"deploy\": \"convex deploy\"\n },\n \"dependencies\": {\n \"convex\": \"^1.25.0\",\n \"@convex-dev/auth\": \"^0.0.90\",\n \"@auth/core\": \"^0.37.0\"\n },\n \"devDependencies\": {\n \"typescript\": \"^5.0.0\"\n }\n}{{/if}}\n",
15
15
  "convex/tsconfig.json.hbs": "{{#if (eq structure 'monorepo')}}{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"noEmit\": true,\n \"outDir\": \"dist\"\n },\n \"include\": [\"convex/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}{{/if}}\n",
16
16
  "integrations/posthog/src/components/providers/posthog-provider.tsx.hbs": "'use client'\n\nimport posthog from 'posthog-js'\nimport { PostHogProvider as PHProvider } from 'posthog-js/react'\nimport { useEffect } from 'react'\n\nexport function PostHogProvider({ children }: { children: React.ReactNode }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',\n person_profiles: 'identified_only',\n capture_pageview: false, // We capture pageviews manually\n })\n }, [])\n\n return <PHProvider client={posthog}>{children}</PHProvider>\n}\n",
17
+ "marketing/nextjs/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default nextConfig\n",
18
+ "marketing/nextjs/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev --turbopack -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 },\n \"dependencies\": {\n \"next\": \"^16.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.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 \"typescript\": \"^5.0.0\"\n }\n}\n",
19
+ "marketing/nextjs/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
20
+ "marketing/nextjs/src/app/globals.css.hbs": "@import \"tailwindcss\";\n\n:root {\n --background: #ffffff;\n --foreground: #171717;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #0a0a0a;\n --foreground: #ededed;\n }\n}\n\nbody {\n color: var(--foreground);\n background: var(--background);\n}\n",
21
+ "marketing/nextjs/src/app/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport { Geist, Geist_Mono } from 'next/font/google'\nimport './globals.css'\n\nconst geistSans = Geist({\n variable: '--font-geist-sans',\n subsets: ['latin'],\n})\n\nconst geistMono = Geist_Mono({\n variable: '--font-geist-mono',\n subsets: ['latin'],\n})\n\nexport const metadata: Metadata = {\n title: '{{projectName}} - Marketing',\n description: 'Marketing site for {{projectName}}',\n}\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <html lang=\"en\">\n <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>\n {children}\n </body>\n </html>\n )\n}\n",
22
+ "marketing/nextjs/src/app/page.tsx.hbs": "export default function HomePage() {\n return (\n <main className=\"min-h-screen\">\n {/* Hero Section */}\n <section className=\"relative overflow-hidden bg-gradient-to-b from-gray-50 to-white dark:from-gray-900 dark:to-gray-800\">\n <div className=\"container mx-auto px-4 py-24 sm:py-32\">\n <div className=\"text-center\">\n <h1 className=\"text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-6xl\">\n Welcome to {{projectName}}\n </h1>\n <p className=\"mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300 max-w-2xl mx-auto\">\n A modern full-stack application built with Next.js, Convex, and Better-Auth.\n </p>\n <div className=\"mt-10 flex items-center justify-center gap-x-6\">\n <a\n href=\"/app\"\n className=\"rounded-lg bg-gray-900 dark:bg-white px-6 py-3 text-sm font-semibold text-white dark:text-gray-900 shadow-sm hover:opacity-90 transition-opacity\"\n >\n Get Started\n </a>\n <a\n href=\"#features\"\n className=\"text-sm font-semibold leading-6 text-gray-900 dark:text-white\"\n >\n Learn more <span aria-hidden=\"true\">→</span>\n </a>\n </div>\n </div>\n </div>\n </section>\n\n {/* Features Section */}\n <section id=\"features\" className=\"py-24 sm:py-32\">\n <div className=\"container mx-auto px-4\">\n <div className=\"text-center mb-16\">\n <h2 className=\"text-3xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-4xl\">\n Everything you need\n </h2>\n <p className=\"mt-4 text-lg text-gray-600 dark:text-gray-300\">\n Built with the best tools for modern web development\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-8\">\n <div className=\"p-6 rounded-xl border border-gray-200 dark:border-gray-700\">\n <div className=\"w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4\">\n <svg className=\"w-6 h-6 text-gray-900 dark:text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 10V3L4 14h7v7l9-11h-7z\" />\n </svg>\n </div>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white mb-2\">\n Lightning Fast\n </h3>\n <p className=\"text-gray-600 dark:text-gray-300\">\n Built on Next.js with Turbopack for instant hot reload and optimized production builds.\n </p>\n </div>\n <div className=\"p-6 rounded-xl border border-gray-200 dark:border-gray-700\">\n <div className=\"w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4\">\n <svg className=\"w-6 h-6 text-gray-900 dark:text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4\" />\n </svg>\n </div>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white mb-2\">\n Real-time Database\n </h3>\n <p className=\"text-gray-600 dark:text-gray-300\">\n Powered by Convex for automatic real-time sync and type-safe queries.\n </p>\n </div>\n <div className=\"p-6 rounded-xl border border-gray-200 dark:border-gray-700\">\n <div className=\"w-12 h-12 bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4\">\n <svg className=\"w-6 h-6 text-gray-900 dark:text-white\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\" />\n </svg>\n </div>\n <h3 className=\"text-lg font-semibold text-gray-900 dark:text-white mb-2\">\n Secure Auth\n </h3>\n <p className=\"text-gray-600 dark:text-gray-300\">\n Better-Auth provides secure, flexible authentication with social login support.\n </p>\n </div>\n </div>\n </div>\n </section>\n\n {/* CTA Section */}\n <section className=\"py-24 sm:py-32 bg-gray-900 dark:bg-gray-800\">\n <div className=\"container mx-auto px-4 text-center\">\n <h2 className=\"text-3xl font-bold tracking-tight text-white sm:text-4xl\">\n Ready to get started?\n </h2>\n <p className=\"mt-4 text-lg text-gray-300 max-w-2xl mx-auto\">\n Start building your next project with our full-stack template.\n </p>\n <div className=\"mt-10\">\n <a\n href=\"/app\"\n className=\"rounded-lg bg-white px-6 py-3 text-sm font-semibold text-gray-900 shadow-sm hover:opacity-90 transition-opacity\"\n >\n Launch App\n </a>\n </div>\n </div>\n </section>\n\n {/* Footer */}\n <footer className=\"border-t border-gray-200 dark:border-gray-700\">\n <div className=\"container mx-auto px-4 py-12\">\n <div className=\"text-center text-gray-600 dark:text-gray-300\">\n <p>\n Built with{' '}\n <a\n href=\"https://github.com/theodenanyoh11/create-kofi-stack\"\n className=\"text-gray-900 dark:text-white hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n create-kofi-stack\n </a>\n </p>\n </div>\n </div>\n </footer>\n </main>\n )\n}\n",
23
+ "marketing/nextjs/tsconfig.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2017\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"jsx\": \"react-jsx\",\n \"incremental\": true,\n \"plugins\": [{ \"name\": \"next\" }],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\", \".next/dev/types/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}\n",
24
+ "marketing/payload/_env.example.hbs": "# Database (Supabase PostgreSQL)\nDATABASE_URL=\"postgresql://postgres:[PASSWORD]@db.[PROJECT].supabase.co:5432/postgres\"\n\n# Payload CMS\nPAYLOAD_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# Scheduled Jobs\nCRON_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# Draft Previews\nPREVIEW_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# S3 Storage (Supabase Storage)\nS3_BUCKET=\"media\"\nS3_ACCESS_KEY_ID=\"\"\nS3_SECRET_ACCESS_KEY=\"\"\nS3_REGION=\"auto\"\nS3_ENDPOINT=\"https://[PROJECT].supabase.co/storage/v1/s3\"\n",
25
+ "marketing/payload/_env.local.hbs": "# Database (Supabase PostgreSQL)\nDATABASE_URL=\"postgresql://postgres:[PASSWORD]@db.[PROJECT].supabase.co:5432/postgres\"\n\n# Payload CMS\nPAYLOAD_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# Scheduled Jobs\nCRON_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# Draft Previews\nPREVIEW_SECRET=\"\" # Generate with: openssl rand -base64 32\n\n# S3 Storage (Supabase Storage)\nS3_BUCKET=\"media\"\nS3_ACCESS_KEY_ID=\"\"\nS3_SECRET_ACCESS_KEY=\"\"\nS3_REGION=\"auto\"\nS3_ENDPOINT=\"https://[PROJECT].supabase.co/storage/v1/s3\"\n",
26
+ "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 experimental: {\n turbo: {},\n },\n}\n\nexport default withPayload(nextConfig)\n",
27
+ "marketing/payload/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev --turbopack -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/storage-s3\": \"^3.0.0\",\n \"@payloadcms/plugin-seo\": \"^3.0.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",
28
+ "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
29
+ "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",
30
+ "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",
31
+ "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",
32
+ "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",
33
+ "marketing/payload/src/app/(payload)/api/[...slug]/route.ts.hbs": "import config from '@/payload.config'\nimport { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const GET = REST_GET(config, importMap)\nexport const POST = REST_POST(config, importMap)\nexport const DELETE = REST_DELETE(config, importMap)\nexport const PATCH = REST_PATCH(config, importMap)\nexport const OPTIONS = REST_OPTIONS(config)\n",
34
+ "marketing/payload/src/app/(payload)/api/graphql/route.ts.hbs": "import config from '@/payload.config'\nimport { GRAPHQL_POST } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const POST = GRAPHQL_POST(config, importMap)\n",
35
+ "marketing/payload/src/app/(payload)/api/graphql-playground/route.ts.hbs": "import config from '@/payload.config'\nimport { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'\nimport { importMap } from '../../importMap.js'\n\nexport const GET = GRAPHQL_PLAYGROUND_GET(config, importMap)\n",
36
+ "marketing/payload/src/app/(payload)/custom.scss.hbs": "/* Custom Payload admin styles */\n",
37
+ "marketing/payload/src/app/(payload)/importMap.js.hbs": "export const importMap = {}\n",
38
+ "marketing/payload/src/app/(payload)/layout.tsx.hbs": "import type { Metadata } from 'next'\nimport config from '@/payload.config'\nimport { RootLayout } from '@payloadcms/next/layouts'\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 Layout = ({ children }: LayoutArgs) =>\n RootLayout({ children, config, importMap })\n\nexport default Layout\n",
39
+ "marketing/payload/src/app/globals.css.hbs": "@import \"tailwindcss\";\n\n@layer base {\n * {\n @apply border-border;\n }\n\n body {\n @apply bg-background text-foreground;\n }\n}\n",
40
+ "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",
41
+ "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",
42
+ "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",
43
+ "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",
44
+ "marketing/payload/src/blocks/FAQ.ts.hbs": "import type { Block } from 'payload'\n\nexport const FAQBlock: Block = {\n slug: 'faq',\n labels: { singular: 'FAQ', plural: 'FAQs' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'items',\n type: 'array',\n fields: [\n { name: 'question', type: 'text', required: true },\n { name: 'answer', type: 'textarea', required: true },\n ],\n },\n ],\n}\n",
45
+ "marketing/payload/src/blocks/Features.ts.hbs": "import type { Block } from 'payload'\n\nexport const FeaturesBlock: Block = {\n slug: 'features',\n labels: { singular: 'Features', plural: 'Features' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'features',\n type: 'array',\n fields: [\n {\n name: 'icon',\n type: 'select',\n options: [\n { label: 'Zap', value: 'zap' },\n { label: 'Shield', value: 'shield' },\n { label: 'Globe', value: 'globe' },\n { label: 'Layers', value: 'layers' },\n { label: 'Settings', value: 'settings' },\n { label: 'Users', value: 'users' },\n { label: 'Lock', value: 'lock' },\n { label: 'Star', value: 'star' },\n ],\n },\n { name: 'title', type: 'text', required: true },\n { name: 'description', type: 'textarea' },\n ],\n },\n ],\n}\n",
46
+ "marketing/payload/src/blocks/Hero.ts.hbs": "import type { Block } from 'payload'\n\nexport const HeroBlock: Block = {\n slug: 'hero',\n labels: { singular: 'Hero', plural: 'Heroes' },\n fields: [\n {\n name: 'heading',\n type: 'text',\n required: true,\n },\n {\n name: 'subheading',\n type: 'textarea',\n },\n {\n name: 'image',\n type: 'upload',\n relationTo: 'media',\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 ],\n defaultValue: 'primary',\n },\n ],\n },\n ],\n}\n",
47
+ "marketing/payload/src/blocks/LogoBanner.ts.hbs": "import type { Block } from 'payload'\n\nexport const LogoBannerBlock: Block = {\n slug: 'logoBanner',\n labels: { singular: 'Logo Banner', plural: 'Logo Banners' },\n fields: [\n { name: 'heading', type: 'text' },\n {\n name: 'logos',\n type: 'array',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'logo', type: 'upload', relationTo: 'media' },\n ],\n },\n ],\n}\n",
48
+ "marketing/payload/src/blocks/Pricing.ts.hbs": "import type { Block } from 'payload'\n\nexport const PricingBlock: Block = {\n slug: 'pricing',\n labels: { singular: 'Pricing', plural: 'Pricing' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'plans',\n type: 'array',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'price', type: 'text', required: true },\n { name: 'period', type: 'text', defaultValue: '/month' },\n { name: 'description', type: 'textarea' },\n { name: 'featured', type: 'checkbox', defaultValue: false },\n {\n name: 'features',\n type: 'array',\n fields: [\n { name: 'feature', type: 'text', required: true },\n { name: 'included', type: 'checkbox', defaultValue: true },\n ],\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 ],\n}\n",
49
+ "marketing/payload/src/blocks/Testimonials.ts.hbs": "import type { Block } from 'payload'\n\nexport const TestimonialsBlock: Block = {\n slug: 'testimonials',\n labels: { singular: 'Testimonials', plural: 'Testimonials' },\n fields: [\n { name: 'heading', type: 'text' },\n { name: 'subheading', type: 'textarea' },\n {\n name: 'testimonials',\n type: 'array',\n fields: [\n { name: 'quote', type: 'textarea', required: true },\n { name: 'author', type: 'text', required: true },\n { name: 'role', type: 'text' },\n { name: 'company', type: 'text' },\n { name: 'image', type: 'upload', relationTo: 'media' },\n ],\n },\n ],\n}\n",
50
+ "marketing/payload/src/blocks/index.ts.hbs": "export { HeroBlock } from './Hero'\nexport { LogoBannerBlock } from './LogoBanner'\nexport { FeaturesBlock } from './Features'\nexport { BenefitsBlock } from './Benefits'\nexport { PricingBlock } from './Pricing'\nexport { TestimonialsBlock } from './Testimonials'\nexport { FAQBlock } from './FAQ'\nexport { ContentBlock } from './Content'\nexport { CTABlock } from './CTA'\n",
51
+ "marketing/payload/src/collections/Media.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Media: CollectionConfig = {\n slug: 'media',\n access: {\n read: () => true,\n },\n upload: {\n staticDir: 'media',\n imageSizes: [\n {\n name: 'thumbnail',\n width: 400,\n height: 300,\n position: 'centre',\n },\n {\n name: 'card',\n width: 768,\n height: 432,\n position: 'centre',\n },\n {\n name: 'hero',\n width: 1920,\n height: 1080,\n position: 'centre',\n },\n ],\n adminThumbnail: 'thumbnail',\n mimeTypes: ['image/*'],\n },\n fields: [\n {\n name: 'alt',\n type: 'text',\n required: true,\n },\n {\n name: 'caption',\n type: 'text',\n },\n ],\n}\n",
52
+ "marketing/payload/src/collections/Pages.ts.hbs": "import type { CollectionConfig } from 'payload'\nimport {\n HeroBlock,\n LogoBannerBlock,\n FeaturesBlock,\n BenefitsBlock,\n PricingBlock,\n TestimonialsBlock,\n FAQBlock,\n ContentBlock,\n CTABlock,\n} from '../blocks'\n\nexport const Pages: CollectionConfig = {\n slug: 'pages',\n admin: {\n useAsTitle: 'title',\n defaultColumns: ['title', 'slug', 'status', 'updatedAt'],\n },\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n unique: true,\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Published', value: 'published' },\n ],\n defaultValue: 'draft',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n HeroBlock,\n LogoBannerBlock,\n FeaturesBlock,\n BenefitsBlock,\n PricingBlock,\n TestimonialsBlock,\n FAQBlock,\n ContentBlock,\n CTABlock,\n ],\n },\n ],\n}\n",
53
+ "marketing/payload/src/collections/Posts.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Posts: CollectionConfig = {\n slug: 'posts',\n admin: {\n useAsTitle: 'title',\n defaultColumns: ['title', 'author', 'status', 'publishedAt'],\n },\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n unique: true,\n },\n {\n name: 'excerpt',\n type: 'textarea',\n },\n {\n name: 'content',\n type: 'richText',\n },\n {\n name: 'featuredImage',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'author',\n type: 'relationship',\n relationTo: 'users',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'status',\n type: 'select',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Published', value: 'published' },\n ],\n defaultValue: 'draft',\n admin: {\n position: 'sidebar',\n },\n },\n {\n name: 'publishedAt',\n type: 'date',\n admin: {\n position: 'sidebar',\n },\n },\n ],\n}\n",
54
+ "marketing/payload/src/collections/Users.ts.hbs": "import type { CollectionConfig } from 'payload'\n\nexport const Users: CollectionConfig = {\n slug: 'users',\n admin: {\n useAsTitle: 'email',\n },\n auth: true,\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n {\n name: 'role',\n type: 'select',\n options: [\n { label: 'Admin', value: 'admin' },\n { label: 'Editor', value: 'editor' },\n ],\n defaultValue: 'editor',\n required: true,\n },\n ],\n}\n",
55
+ "marketing/payload/src/collections/index.ts.hbs": "export { Users } from './Users'\nexport { Media } from './Media'\nexport { Pages } from './Pages'\nexport { Posts } from './Posts'\n",
56
+ "marketing/payload/src/globals/Navigation.ts.hbs": "import type { GlobalConfig } from 'payload'\n\nexport const Navigation: GlobalConfig = {\n slug: 'navigation',\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'label',\n type: 'text',\n required: true,\n },\n {\n name: 'link',\n type: 'group',\n fields: [\n {\n name: 'type',\n type: 'radio',\n options: [\n { label: 'Internal', value: 'internal' },\n { label: 'External', value: 'external' },\n ],\n defaultValue: 'internal',\n },\n {\n name: 'page',\n type: 'relationship',\n relationTo: 'pages',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'internal',\n },\n },\n {\n name: 'url',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'external',\n },\n },\n ],\n },\n ],\n },\n ],\n}\n",
57
+ "marketing/payload/src/globals/SiteSettings.ts.hbs": "import type { GlobalConfig } from 'payload'\n\nexport const SiteSettings: GlobalConfig = {\n slug: 'site-settings',\n access: {\n read: () => true,\n },\n fields: [\n {\n name: 'siteName',\n type: 'text',\n required: true,\n },\n {\n name: 'siteDescription',\n type: 'textarea',\n },\n {\n name: 'logo',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'favicon',\n type: 'upload',\n relationTo: 'media',\n },\n {\n name: 'socialLinks',\n type: 'array',\n fields: [\n {\n name: 'platform',\n type: 'select',\n options: [\n { label: 'Twitter', value: 'twitter' },\n { label: 'GitHub', value: 'github' },\n { label: 'LinkedIn', value: 'linkedin' },\n { label: 'Discord', value: 'discord' },\n ],\n },\n {\n name: 'url',\n type: 'text',\n },\n ],\n },\n ],\n}\n",
58
+ "marketing/payload/src/globals/index.ts.hbs": "export { SiteSettings } from './SiteSettings'\nexport { Navigation } from './Navigation'\n",
59
+ "marketing/payload/src/payload.config.ts.hbs": "import path from 'path'\nimport { fileURLToPath } from 'url'\nimport { buildConfig } from 'payload'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { s3Storage } from '@payloadcms/storage-s3'\nimport { seoPlugin } from '@payloadcms/plugin-seo'\n\nimport { Pages } from './collections/Pages'\nimport { Media } from './collections/Media'\nimport { Users } from './collections/Users'\nimport { Posts } from './collections/Posts'\nimport { SiteSettings } from './globals/SiteSettings'\nimport { Navigation } from './globals/Navigation'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nexport default buildConfig({\n admin: {\n user: Users.slug,\n importMap: {\n baseDir: path.resolve(__dirname),\n },\n },\n db: postgresAdapter({\n pool: {\n connectionString: process.env.DATABASE_URL,\n },\n }),\n editor: lexicalEditor(),\n collections: [Users, Media, Pages, Posts],\n globals: [SiteSettings, Navigation],\n plugins: [\n s3Storage({\n collections: {\n media: true,\n },\n bucket: process.env.S3_BUCKET!,\n config: {\n credentials: {\n accessKeyId: process.env.S3_ACCESS_KEY_ID!,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,\n },\n region: process.env.S3_REGION!,\n endpoint: process.env.S3_ENDPOINT!,\n forcePathStyle: true,\n },\n }),\n seoPlugin({\n collections: ['pages', 'posts'],\n uploadsCollection: 'media',\n generateTitle: ({ doc }) => `${doc?.title ?? ''} | {{projectName}}`,\n generateDescription: ({ doc }) => doc?.excerpt ?? '',\n }),\n ],\n secret: process.env.PAYLOAD_SECRET!,\n typescript: {\n outputFile: path.resolve(__dirname, 'payload-types.ts'),\n },\n})\n",
60
+ "marketing/payload/tsconfig.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2017\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"jsx\": \"react-jsx\",\n \"incremental\": true,\n \"plugins\": [{ \"name\": \"next\" }],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\", \".next/dev/types/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}\n",
17
61
  "monorepo/package.json.hbs": "{\n \"name\": \"{{projectName}}\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"node scripts/dev.mjs\",\n \"dev:all\": \"turbo dev\",\n \"dev:web\": \"turbo -F @repo/web dev\",\n \"dev:backend\": \"turbo -F @repo/backend dev\",\n \"dev:setup\": \"turbo -F @repo/backend dev:setup\",\n \"build\": \"turbo build\",\n \"lint\": \"turbo lint\",\n \"lint:fix\": \"turbo lint:fix\",\n \"format\": \"turbo format\",\n \"typecheck\": \"turbo typecheck\",\n \"test\": \"turbo test\",\n \"test:e2e\": \"turbo test:e2e\",\n \"clean\": \"turbo clean && rm -rf node_modules\",\n \"prepare\": \"husky\"\n },\n \"devDependencies\": {\n \"turbo\": \"^2.0.0\",\n \"husky\": \"^9.0.0\",\n \"lint-staged\": \"^15.0.0\"\n },\n \"packageManager\": \"pnpm@9.0.0\",\n \"lint-staged\": {\n \"*.{js,ts,jsx,tsx}\": [\"biome check --apply\"],\n \"*.{json,md}\": [\"biome format --write\"]\n }\n}\n",
18
62
  "monorepo/pnpm-workspace.yaml.hbs": "packages:\n - \"apps/*\"\n - \"packages/*\"\n",
19
- "monorepo/turbo.json.hbs": "{\n \"$schema\": \"https://turbo.build/schema.json\",\n \"ui\": \"tui\",\n \"tasks\": {\n \"build\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n \"outputs\": [\".next/**\", \"!.next/cache/**\", \"dist/**\"]\n },\n \"lint\": {\n \"dependsOn\": [\"^lint\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"lint:fix\": {\n \"dependsOn\": [\"^lint:fix\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"format\": {\n \"dependsOn\": [\"^format\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"typecheck\": {\n \"dependsOn\": [\"^typecheck\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"dev\": {\n \"cache\": false,\n \"persistent\": true\n },\n \"test\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"test:e2e\": {\n \"dependsOn\": [\"build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"clean\": {\n \"cache\": false\n }\n }\n}\n",
63
+ "monorepo/turbo.json.hbs": "{\n \"$schema\": \"https://turbo.build/schema.json\",\n \"ui\": \"tui\",\n \"tasks\": {\n \"build\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n \"outputs\": [\".next/**\", \"!.next/cache/**\", \"dist/**\"]\n },\n \"lint\": {\n \"dependsOn\": [\"^lint\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"lint:fix\": {\n \"dependsOn\": [\"^lint:fix\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"format\": {\n \"dependsOn\": [\"^format\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"typecheck\": {\n \"dependsOn\": [\"^typecheck\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"dev\": {\n \"cache\": false,\n \"persistent\": true\n },\n \"dev:setup\": {\n \"cache\": false\n },\n \"test\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"test:e2e\": {\n \"dependsOn\": [\"build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"clean\": {\n \"cache\": false\n }\n }\n}\n",
20
64
  "packages/config-biome/biome.json.hbs": "{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"extends\": [\"../../biome.json\"]\n}\n",
21
65
  "packages/config-biome/package.json.hbs": "{\n \"name\": \"@repo/config-biome\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"files\": [\"biome.json\"]\n}\n",
22
66
  "packages/config-typescript/base.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"incremental\": true\n },\n \"exclude\": [\"node_modules\"]\n}\n",
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from 'next'
2
+
3
+ const nextConfig: NextConfig = {
4
+ transpilePackages: ['@repo/ui'],
5
+ }
6
+
7
+ export default nextConfig
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@repo/marketing",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --turbopack -p 3001",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "biome check .",
10
+ "lint:fix": "biome check --write .",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "next": "^16.0.0",
15
+ "react": "^19.0.0",
16
+ "react-dom": "^19.0.0",
17
+ "@repo/ui": "workspace:*"
18
+ },
19
+ "devDependencies": {
20
+ "@repo/config-typescript": "workspace:*",
21
+ "@types/node": "^20.0.0",
22
+ "@types/react": "^19.0.0",
23
+ "@types/react-dom": "^19.0.0",
24
+ "tailwindcss": "^4.0.0",
25
+ "@tailwindcss/postcss": "^4.0.0",
26
+ "postcss": "^8.4.0",
27
+ "typescript": "^5.0.0"
28
+ }
29
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ plugins: {
3
+ '@tailwindcss/postcss': {},
4
+ },
5
+ }