kofi-stack-template-generator 2.1.43 → 2.1.44

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.
@@ -1,9 +1,9 @@
1
1
 
2
- > kofi-stack-template-generator@2.1.43 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
2
+ > kofi-stack-template-generator@2.1.44 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.1.43 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
6
+ > kofi-stack-template-generator@2.1.44 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...
@@ -14,7 +14,7 @@ CLI tsup v8.5.1
14
14
  CLI Target: es2022
15
15
  ESM Build start
16
16
  ESM dist/index.js 2.28 MB
17
- ESM ⚡️ Build success in 55ms
17
+ ESM ⚡️ Build success in 67ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 499ms
19
+ DTS ⚡️ Build success in 554ms
20
20
  DTS dist/index.d.ts 2.96 KB
package/dist/index.js CHANGED
@@ -1415,7 +1415,7 @@ GCS_CREDENTIALS="{}" # JSON service account key
1415
1415
  `,
1416
1416
  "marketing/payload/_env.local.hbs": "# Database (Supabase PostgreSQL)\nDATABASE_URL=\n\n# Payload CMS\nPAYLOAD_SECRET=\n\n# Scheduled Jobs\nCRON_SECRET=\n\n# Draft Previews\nPREVIEW_SECRET=\n\n# Email (Resend)\nRESEND_API_KEY=\nRESEND_FROM_EMAIL=\n\n{{#if (eq integrations.payloadStorage 's3')}}\n# S3 Storage\nS3_BUCKET=media\nS3_ACCESS_KEY_ID=\nS3_SECRET_ACCESS_KEY=\nS3_REGION=us-east-1\nS3_ENDPOINT=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'r2')}}\n# Cloudflare R2 Storage\nR2_BUCKET=\nR2_ACCESS_KEY_ID=\nR2_SECRET_ACCESS_KEY=\nR2_ENDPOINT=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'vercel-blob')}}\n# Vercel Blob Storage\nBLOB_READ_WRITE_TOKEN=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'gcs')}}\n# Google Cloud Storage\nGCS_BUCKET=\nGCS_PROJECT_ID=\nGCS_CREDENTIALS=\n{{/if}}\n",
1417
1417
  "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",
1418
- "marketing/payload/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "type": "module",\n "scripts": {\n "build": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap && next build",\n "dev": "cross-env NODE_OPTIONS=--no-deprecation next dev --port 3000",\n "generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",\n "generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",\n "lint": "biome check .",\n "lint:fix": "biome check --write .",\n "payload": "cross-env NODE_OPTIONS=--no-deprecation payload",\n "start": "cross-env NODE_OPTIONS=--no-deprecation next start",\n "typecheck": "tsc --noEmit",\n "db:push": "payload migrate",\n "db:seed": "tsx src/seed.ts"\n },\n "dependencies": {\n "@payloadcms/admin-bar": "^3.0.0",\n "@payloadcms/db-postgres": "^3.0.0",\n "@payloadcms/email-resend": "^3.0.0",\n "@payloadcms/live-preview-react": "^3.0.0",\n "@payloadcms/next": "^3.0.0",\n "@payloadcms/plugin-form-builder": "^3.0.0",\n "@payloadcms/plugin-nested-docs": "^3.0.0",\n "@payloadcms/plugin-redirects": "^3.0.0",\n "@payloadcms/plugin-search": "^3.0.0",\n "@payloadcms/plugin-seo": "^3.0.0",\n "@payloadcms/richtext-lexical": "^3.0.0",\n "@payloadcms/storage-vercel-blob": "^3.0.0",\n "@payloadcms/ui": "^3.0.0",\n "@radix-ui/react-accordion": "^1.2.0",\n "@radix-ui/react-checkbox": "^1.0.4",\n "@radix-ui/react-label": "^2.0.2",\n "@radix-ui/react-select": "^2.0.0",\n "@radix-ui/react-slot": "^1.0.2",\n "@repo/ui": "workspace:*",\n "class-variance-authority": "^0.7.1",\n "clsx": "^2.1.1",\n "cross-env": "^7.0.3",\n "geist": "^1.3.0",\n "lucide-react": "^0.562.0",\n "next": "^15.4.10",\n "payload": "^3.70.0",\n "posthog-js": "^1.200.0",\n "prism-react-renderer": "^2.4.1",\n "react": "^19.0.0",\n "react-dom": "^19.0.0",\n "react-hook-form": "^7.71.1",\n "sharp": "^0.34.0",\n "tailwind-merge": "^3.4.0"\n },\n "devDependencies": {\n "@repo/config-typescript": "workspace:*",\n "@tailwindcss/postcss": "^4.0.0",\n "@tailwindcss/typography": "^0.5.19",\n "@types/node": "^20.0.0",\n "@types/react": "^19.0.0",\n "@types/react-dom": "^19.0.0",\n "postcss": "^8.4.0",\n "sass": "^1.86.0",\n "tailwindcss": "^4.0.0",\n "tsx": "^4.0.0",\n "tw-animate-css": "^1.4.0",\n "typescript": "^5.0.0"\n }\n}\n',
1418
+ "marketing/payload/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "type": "module",\n "scripts": {\n "build": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap && next build",\n "dev": "cross-env NODE_OPTIONS=--no-deprecation next dev --port 3000",\n "generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",\n "generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",\n "lint": "biome check .",\n "lint:fix": "biome check --write .",\n "payload": "cross-env NODE_OPTIONS=--no-deprecation payload",\n "start": "cross-env NODE_OPTIONS=--no-deprecation next start",\n "typecheck": "tsc --noEmit",\n "db:push": "payload migrate",\n "db:seed": "tsx src/seed.ts"\n },\n "dependencies": {\n "@payloadcms/admin-bar": "^3.0.0",\n "@payloadcms/db-postgres": "^3.0.0",\n "@payloadcms/email-resend": "^3.0.0",\n "@payloadcms/live-preview-react": "^3.0.0",\n "@payloadcms/next": "^3.0.0",\n "@payloadcms/plugin-form-builder": "^3.0.0",\n "@payloadcms/plugin-nested-docs": "^3.0.0",\n "@payloadcms/plugin-redirects": "^3.0.0",\n "@payloadcms/plugin-search": "^3.0.0",\n "@payloadcms/plugin-seo": "^3.0.0",\n "@payloadcms/richtext-lexical": "^3.0.0",\n "@payloadcms/storage-vercel-blob": "^3.0.0",\n "@payloadcms/ui": "^3.0.0",\n "@radix-ui/react-accordion": "^1.2.0",\n "@radix-ui/react-checkbox": "^1.0.4",\n "@radix-ui/react-label": "^2.0.2",\n "@radix-ui/react-select": "^2.0.0",\n "@radix-ui/react-slot": "^1.0.2",\n "@repo/ui": "workspace:*",\n "class-variance-authority": "^0.7.1",\n "clsx": "^2.1.1",\n "cross-env": "^7.0.3",\n "geist": "^1.3.0",\n "lucide-react": "^0.562.0",\n "next": "^15.4.10",\n "payload": "^3.70.0",\n "posthog-js": "^1.200.0",\n "prism-react-renderer": "^2.4.1",\n "react": "^19.0.0",\n "react-dom": "^19.0.0",\n "react-hook-form": "^7.71.1",\n "sharp": "^0.34.0",\n "stripe": "^17.7.0",\n "tailwind-merge": "^3.4.0"\n },\n "devDependencies": {\n "@repo/config-typescript": "workspace:*",\n "@tailwindcss/postcss": "^4.0.0",\n "@tailwindcss/typography": "^0.5.19",\n "@types/node": "^20.0.0",\n "@types/react": "^19.0.0",\n "@types/react-dom": "^19.0.0",\n "postcss": "^8.4.0",\n "sass": "^1.86.0",\n "tailwindcss": "^4.0.0",\n "tsx": "^4.0.0",\n "tw-animate-css": "^1.4.0",\n "typescript": "^5.0.0"\n }\n}\n',
1419
1419
  "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
1420
1420
  "marketing/payload/src/Footer/Component.client.tsx": '"use client"\n\nimport Link from "next/link"\nimport type React from "react"\nimport { useState } from "react"\n\nimport type { Footer, Page, Post } from "@/payload-types"\n\nimport { Logo } from "@/components/Logo/Logo"\nimport { Button } from "@/components/ui/button"\nimport { Input } from "@/components/ui/input"\nimport { ThemeSelector } from "@/providers/Theme/ThemeSelector"\nimport { cn } from "@/utilities/ui"\n\ninterface FooterClientProps {\n data: Footer\n}\n\n// Social icons as inline SVGs for flexibility\nconst SocialIcons = {\n twitter: (\n <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">\n <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />\n </svg>\n ),\n instagram: (\n <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">\n <path\n fillRule="evenodd"\n d="M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z"\n clipRule="evenodd"\n />\n </svg>\n ),\n linkedin: (\n <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">\n <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />\n </svg>\n ),\n github: (\n <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">\n <path\n fillRule="evenodd"\n d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"\n clipRule="evenodd"\n />\n </svg>\n ),\n youtube: (\n <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">\n <path\n fillRule="evenodd"\n d="M19.812 5.418c.861.23 1.538.907 1.768 1.768C21.998 8.746 22 12 22 12s0 3.255-.418 4.814a2.504 2.504 0 0 1-1.768 1.768c-1.56.419-7.814.419-7.814.419s-6.255 0-7.814-.419a2.505 2.505 0 0 1-1.768-1.768C2 15.255 2 12 2 12s0-3.255.417-4.814a2.507 2.507 0 0 1 1.768-1.768C5.744 5 11.998 5 11.998 5s6.255 0 7.814.418ZM15.194 12 10 15V9l5.194 3Z"\n clipRule="evenodd"\n />\n </svg>\n ),\n}\n\n// Helper function to get URL from link\nfunction getLinkUrl(link: {\n type?: ("reference" | "custom") | null\n reference?:\n | { relationTo: "pages"; value: number | Page }\n | { relationTo: "posts"; value: number | Post }\n | null\n url?: string | null\n}): string {\n if (link.type === "reference" && link.reference) {\n const value = link.reference.value\n if (typeof value === "object" && "slug" in value) {\n const prefix = link.reference.relationTo === "posts" ? "/posts" : ""\n return `${prefix}/${value.slug}`\n }\n }\n return link.url || "#"\n}\n\nexport const FooterClient: React.FC<FooterClientProps> = ({ data }) => {\n const currentYear = new Date().getFullYear()\n const [email, setEmail] = useState("")\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null)\n\n const { columns, socialLinks, newsletter, copyrightText, bottomLinks } = data\n\n const handleNewsletterSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n if (!email || isSubmitting) return\n\n setIsSubmitting(true)\n setMessage(null)\n\n try {\n const response = await fetch("/api/newsletter", {\n method: "POST",\n headers: { "Content-Type": "application/json" },\n body: JSON.stringify({ email }),\n })\n\n const result = await response.json()\n\n if (result.success) {\n setMessage({ type: "success", text: result.message })\n setEmail("")\n } else {\n setMessage({ type: "error", text: result.message })\n }\n } catch {\n setMessage({ type: "error", text: "Something went wrong. Please try again." })\n } finally {\n setIsSubmitting(false)\n }\n }\n\n // Check if any social links are configured\n const hasSocialLinks =\n socialLinks?.twitter ||\n socialLinks?.instagram ||\n socialLinks?.linkedin ||\n socialLinks?.github ||\n socialLinks?.youtube\n\n return (\n <footer className="mt-auto border-t border-border bg-background">\n {/* Main Footer Content */}\n <div className="container mx-auto px-4 py-12 lg:py-16">\n <div className="grid grid-cols-2 gap-8 md:grid-cols-3 lg:grid-cols-6">\n {/* Link Columns */}\n {columns?.map((column) => (\n <div key={column.id || column.title} className="col-span-1">\n <h3 className="mb-4 text-sm font-medium text-foreground">{column.title}</h3>\n <ul className="space-y-3">\n {column.links?.map((linkItem) => (\n <li key={linkItem.id || linkItem.link.label}>\n <Link\n href={getLinkUrl(linkItem.link)}\n className="text-sm text-muted-foreground transition-colors hover:text-foreground"\n {...(linkItem.link.newTab\n ? { target: "_blank", rel: "noopener noreferrer" }\n : {})}\n >\n {linkItem.link.label}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n\n {/* Newsletter Column */}\n {newsletter?.enabled && (\n <div className="col-span-2 md:col-span-3 lg:col-span-2">\n <h3 className="mb-4 text-sm font-medium text-foreground">\n {newsletter.title || "Newsletter"}\n </h3>\n <p className="mb-4 text-sm text-muted-foreground">\n {newsletter.description || "Stay up to date with the latest updates."}\n </p>\n <form\n onSubmit={handleNewsletterSubmit}\n className="space-y-3"\n suppressHydrationWarning\n >\n <div className="flex gap-2">\n <Input\n type="email"\n placeholder={newsletter.placeholder || "Enter your email"}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className="flex-1"\n disabled={isSubmitting}\n required\n suppressHydrationWarning\n />\n <Button type="submit" disabled={isSubmitting} suppressHydrationWarning>\n {isSubmitting ? "..." : newsletter.buttonText || "Subscribe"}\n </Button>\n </div>\n {message && (\n <p\n className={cn(\n "text-sm",\n message.type === "success" ? "text-green-600" : "text-red-600",\n )}\n >\n {message.text}\n </p>\n )}\n </form>\n </div>\n )}\n </div>\n\n {/* Social Links */}\n {hasSocialLinks && (\n <div className="mt-10 flex items-center gap-4 border-t border-border pt-8">\n {socialLinks?.twitter && (\n <a\n href={socialLinks.twitter}\n target="_blank"\n rel="noopener noreferrer"\n className="text-muted-foreground transition-colors hover:text-foreground"\n aria-label="X (Twitter)"\n >\n {SocialIcons.twitter}\n </a>\n )}\n {socialLinks?.instagram && (\n <a\n href={socialLinks.instagram}\n target="_blank"\n rel="noopener noreferrer"\n className="text-muted-foreground transition-colors hover:text-foreground"\n aria-label="Instagram"\n >\n {SocialIcons.instagram}\n </a>\n )}\n {socialLinks?.linkedin && (\n <a\n href={socialLinks.linkedin}\n target="_blank"\n rel="noopener noreferrer"\n className="text-muted-foreground transition-colors hover:text-foreground"\n aria-label="LinkedIn"\n >\n {SocialIcons.linkedin}\n </a>\n )}\n {socialLinks?.github && (\n <a\n href={socialLinks.github}\n target="_blank"\n rel="noopener noreferrer"\n className="text-muted-foreground transition-colors hover:text-foreground"\n aria-label="GitHub"\n >\n {SocialIcons.github}\n </a>\n )}\n {socialLinks?.youtube && (\n <a\n href={socialLinks.youtube}\n target="_blank"\n rel="noopener noreferrer"\n className="text-muted-foreground transition-colors hover:text-foreground"\n aria-label="YouTube"\n >\n {SocialIcons.youtube}\n </a>\n )}\n </div>\n )}\n </div>\n\n {/* Bottom Bar */}\n <div className="border-t border-border">\n <div className="container mx-auto flex flex-col items-center justify-between gap-4 px-4 py-6 sm:flex-row">\n {/* Logo and Copyright */}\n <div className="flex items-center gap-4">\n <Link href="/" className="flex items-center">\n <Logo variant="auto" className="h-6 w-6" />\n </Link>\n <p className="text-sm text-muted-foreground">\n \xA9 {currentYear} {copyrightText || "DirectoryHub"}\n </p>\n </div>\n\n {/* Bottom Links and Theme Selector */}\n <div className="flex items-center gap-6">\n {bottomLinks?.map((linkItem) => (\n <Link\n key={linkItem.id || linkItem.link.label}\n href={getLinkUrl(linkItem.link)}\n className="text-sm text-muted-foreground transition-colors hover:text-foreground"\n {...(linkItem.link.newTab ? { target: "_blank", rel: "noopener noreferrer" } : {})}\n >\n {linkItem.link.label}\n </Link>\n ))}\n <ThemeSelector />\n </div>\n </div>\n </div>\n </footer>\n )\n}\n',
1421
1421
  "marketing/payload/src/Footer/Component.tsx": 'import { getCachedGlobal } from "@/utilities/getGlobals"\n\nimport type { Footer as FooterType } from "@/payload-types"\n\nimport { FooterClient } from "./Component.client"\n\nexport async function Footer() {\n const footerData: FooterType = await getCachedGlobal("footer", 1)()\n\n return <FooterClient data={footerData} />\n}\n',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.1.43",
3
+ "version": "2.1.44",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "typecheck": "tsc --noEmit"
18
18
  },
19
19
  "dependencies": {
20
- "kofi-stack-types": "^2.1.43",
20
+ "kofi-stack-types": "^2.1.44",
21
21
  "handlebars": "^4.7.8",
22
22
  "memfs": "^4.9.0"
23
23
  },
@@ -1,6 +1,6 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-19T02:33:07.359Z
3
+ // Generated: 2026-01-19T03:06:07.098Z
4
4
  // Template count: 339
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {
@@ -51,7 +51,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
51
51
  "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# Email (Resend)\nRESEND_API_KEY=\"\"\nRESEND_FROM_EMAIL=\"noreply@yourdomain.com\"\n\n{{#if (eq integrations.payloadStorage 's3')}}\n# S3 Storage\nS3_BUCKET=\"media\"\nS3_ACCESS_KEY_ID=\"\"\nS3_SECRET_ACCESS_KEY=\"\"\nS3_REGION=\"us-east-1\"\nS3_ENDPOINT=\"\" # Optional: For S3-compatible services\n{{/if}}\n{{#if (eq integrations.payloadStorage 'r2')}}\n# Cloudflare R2 Storage\nR2_BUCKET=\"\"\nR2_ACCESS_KEY_ID=\"\"\nR2_SECRET_ACCESS_KEY=\"\"\nR2_ENDPOINT=\"https://[ACCOUNT_ID].r2.cloudflarestorage.com\"\n{{/if}}\n{{#if (eq integrations.payloadStorage 'vercel-blob')}}\n# Vercel Blob Storage\nBLOB_READ_WRITE_TOKEN=\"\"\n{{/if}}\n{{#if (eq integrations.payloadStorage 'gcs')}}\n# Google Cloud Storage\nGCS_BUCKET=\"\"\nGCS_PROJECT_ID=\"\"\nGCS_CREDENTIALS=\"{}\" # JSON service account key\n{{/if}}\n{{#if (eq integrations.payloadStorage 'local')}}\n# Local Storage\n# Files are stored in the /media directory by default\n# No additional configuration required\n{{/if}}\n",
52
52
  "marketing/payload/_env.local.hbs": "# Database (Supabase PostgreSQL)\nDATABASE_URL=\n\n# Payload CMS\nPAYLOAD_SECRET=\n\n# Scheduled Jobs\nCRON_SECRET=\n\n# Draft Previews\nPREVIEW_SECRET=\n\n# Email (Resend)\nRESEND_API_KEY=\nRESEND_FROM_EMAIL=\n\n{{#if (eq integrations.payloadStorage 's3')}}\n# S3 Storage\nS3_BUCKET=media\nS3_ACCESS_KEY_ID=\nS3_SECRET_ACCESS_KEY=\nS3_REGION=us-east-1\nS3_ENDPOINT=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'r2')}}\n# Cloudflare R2 Storage\nR2_BUCKET=\nR2_ACCESS_KEY_ID=\nR2_SECRET_ACCESS_KEY=\nR2_ENDPOINT=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'vercel-blob')}}\n# Vercel Blob Storage\nBLOB_READ_WRITE_TOKEN=\n{{/if}}\n{{#if (eq integrations.payloadStorage 'gcs')}}\n# Google Cloud Storage\nGCS_BUCKET=\nGCS_PROJECT_ID=\nGCS_CREDENTIALS=\n{{/if}}\n",
53
53
  "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",
54
- "marketing/payload/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap && next build\",\n \"dev\": \"cross-env NODE_OPTIONS=--no-deprecation next dev --port 3000\",\n \"generate:importmap\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap\",\n \"generate:types\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:types\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"payload\": \"cross-env NODE_OPTIONS=--no-deprecation payload\",\n \"start\": \"cross-env NODE_OPTIONS=--no-deprecation next start\",\n \"typecheck\": \"tsc --noEmit\",\n \"db:push\": \"payload migrate\",\n \"db:seed\": \"tsx src/seed.ts\"\n },\n \"dependencies\": {\n \"@payloadcms/admin-bar\": \"^3.0.0\",\n \"@payloadcms/db-postgres\": \"^3.0.0\",\n \"@payloadcms/email-resend\": \"^3.0.0\",\n \"@payloadcms/live-preview-react\": \"^3.0.0\",\n \"@payloadcms/next\": \"^3.0.0\",\n \"@payloadcms/plugin-form-builder\": \"^3.0.0\",\n \"@payloadcms/plugin-nested-docs\": \"^3.0.0\",\n \"@payloadcms/plugin-redirects\": \"^3.0.0\",\n \"@payloadcms/plugin-search\": \"^3.0.0\",\n \"@payloadcms/plugin-seo\": \"^3.0.0\",\n \"@payloadcms/richtext-lexical\": \"^3.0.0\",\n \"@payloadcms/storage-vercel-blob\": \"^3.0.0\",\n \"@payloadcms/ui\": \"^3.0.0\",\n \"@radix-ui/react-accordion\": \"^1.2.0\",\n \"@radix-ui/react-checkbox\": \"^1.0.4\",\n \"@radix-ui/react-label\": \"^2.0.2\",\n \"@radix-ui/react-select\": \"^2.0.0\",\n \"@radix-ui/react-slot\": \"^1.0.2\",\n \"@repo/ui\": \"workspace:*\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cross-env\": \"^7.0.3\",\n \"geist\": \"^1.3.0\",\n \"lucide-react\": \"^0.562.0\",\n \"next\": \"^15.4.10\",\n \"payload\": \"^3.70.0\",\n \"posthog-js\": \"^1.200.0\",\n \"prism-react-renderer\": \"^2.4.1\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"react-hook-form\": \"^7.71.1\",\n \"sharp\": \"^0.34.0\",\n \"tailwind-merge\": \"^3.4.0\"\n },\n \"devDependencies\": {\n \"@repo/config-typescript\": \"workspace:*\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"@tailwindcss/typography\": \"^0.5.19\",\n \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"postcss\": \"^8.4.0\",\n \"sass\": \"^1.86.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"tsx\": \"^4.0.0\",\n \"tw-animate-css\": \"^1.4.0\",\n \"typescript\": \"^5.0.0\"\n }\n}\n",
54
+ "marketing/payload/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap && next build\",\n \"dev\": \"cross-env NODE_OPTIONS=--no-deprecation next dev --port 3000\",\n \"generate:importmap\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap\",\n \"generate:types\": \"cross-env NODE_OPTIONS=--no-deprecation payload generate:types\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"payload\": \"cross-env NODE_OPTIONS=--no-deprecation payload\",\n \"start\": \"cross-env NODE_OPTIONS=--no-deprecation next start\",\n \"typecheck\": \"tsc --noEmit\",\n \"db:push\": \"payload migrate\",\n \"db:seed\": \"tsx src/seed.ts\"\n },\n \"dependencies\": {\n \"@payloadcms/admin-bar\": \"^3.0.0\",\n \"@payloadcms/db-postgres\": \"^3.0.0\",\n \"@payloadcms/email-resend\": \"^3.0.0\",\n \"@payloadcms/live-preview-react\": \"^3.0.0\",\n \"@payloadcms/next\": \"^3.0.0\",\n \"@payloadcms/plugin-form-builder\": \"^3.0.0\",\n \"@payloadcms/plugin-nested-docs\": \"^3.0.0\",\n \"@payloadcms/plugin-redirects\": \"^3.0.0\",\n \"@payloadcms/plugin-search\": \"^3.0.0\",\n \"@payloadcms/plugin-seo\": \"^3.0.0\",\n \"@payloadcms/richtext-lexical\": \"^3.0.0\",\n \"@payloadcms/storage-vercel-blob\": \"^3.0.0\",\n \"@payloadcms/ui\": \"^3.0.0\",\n \"@radix-ui/react-accordion\": \"^1.2.0\",\n \"@radix-ui/react-checkbox\": \"^1.0.4\",\n \"@radix-ui/react-label\": \"^2.0.2\",\n \"@radix-ui/react-select\": \"^2.0.0\",\n \"@radix-ui/react-slot\": \"^1.0.2\",\n \"@repo/ui\": \"workspace:*\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cross-env\": \"^7.0.3\",\n \"geist\": \"^1.3.0\",\n \"lucide-react\": \"^0.562.0\",\n \"next\": \"^15.4.10\",\n \"payload\": \"^3.70.0\",\n \"posthog-js\": \"^1.200.0\",\n \"prism-react-renderer\": \"^2.4.1\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"react-hook-form\": \"^7.71.1\",\n \"sharp\": \"^0.34.0\",\n \"stripe\": \"^17.7.0\",\n \"tailwind-merge\": \"^3.4.0\"\n },\n \"devDependencies\": {\n \"@repo/config-typescript\": \"workspace:*\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"@tailwindcss/typography\": \"^0.5.19\",\n \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"postcss\": \"^8.4.0\",\n \"sass\": \"^1.86.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"tsx\": \"^4.0.0\",\n \"tw-animate-css\": \"^1.4.0\",\n \"typescript\": \"^5.0.0\"\n }\n}\n",
55
55
  "marketing/payload/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
56
56
  "marketing/payload/src/Footer/Component.client.tsx": "\"use client\"\n\nimport Link from \"next/link\"\nimport type React from \"react\"\nimport { useState } from \"react\"\n\nimport type { Footer, Page, Post } from \"@/payload-types\"\n\nimport { Logo } from \"@/components/Logo/Logo\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { ThemeSelector } from \"@/providers/Theme/ThemeSelector\"\nimport { cn } from \"@/utilities/ui\"\n\ninterface FooterClientProps {\n\tdata: Footer\n}\n\n// Social icons as inline SVGs for flexibility\nconst SocialIcons = {\n\ttwitter: (\n\t\t<svg className=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n\t\t\t<path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n\t\t</svg>\n\t),\n\tinstagram: (\n\t\t<svg className=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n\t\t\t<path\n\t\t\t\tfillRule=\"evenodd\"\n\t\t\t\td=\"M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z\"\n\t\t\t\tclipRule=\"evenodd\"\n\t\t\t/>\n\t\t</svg>\n\t),\n\tlinkedin: (\n\t\t<svg className=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n\t\t\t<path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n\t\t</svg>\n\t),\n\tgithub: (\n\t\t<svg className=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n\t\t\t<path\n\t\t\t\tfillRule=\"evenodd\"\n\t\t\t\td=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n\t\t\t\tclipRule=\"evenodd\"\n\t\t\t/>\n\t\t</svg>\n\t),\n\tyoutube: (\n\t\t<svg className=\"h-5 w-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n\t\t\t<path\n\t\t\t\tfillRule=\"evenodd\"\n\t\t\t\td=\"M19.812 5.418c.861.23 1.538.907 1.768 1.768C21.998 8.746 22 12 22 12s0 3.255-.418 4.814a2.504 2.504 0 0 1-1.768 1.768c-1.56.419-7.814.419-7.814.419s-6.255 0-7.814-.419a2.505 2.505 0 0 1-1.768-1.768C2 15.255 2 12 2 12s0-3.255.417-4.814a2.507 2.507 0 0 1 1.768-1.768C5.744 5 11.998 5 11.998 5s6.255 0 7.814.418ZM15.194 12 10 15V9l5.194 3Z\"\n\t\t\t\tclipRule=\"evenodd\"\n\t\t\t/>\n\t\t</svg>\n\t),\n}\n\n// Helper function to get URL from link\nfunction getLinkUrl(link: {\n\ttype?: (\"reference\" | \"custom\") | null\n\treference?:\n\t\t| { relationTo: \"pages\"; value: number | Page }\n\t\t| { relationTo: \"posts\"; value: number | Post }\n\t\t| null\n\turl?: string | null\n}): string {\n\tif (link.type === \"reference\" && link.reference) {\n\t\tconst value = link.reference.value\n\t\tif (typeof value === \"object\" && \"slug\" in value) {\n\t\t\tconst prefix = link.reference.relationTo === \"posts\" ? \"/posts\" : \"\"\n\t\t\treturn `${prefix}/${value.slug}`\n\t\t}\n\t}\n\treturn link.url || \"#\"\n}\n\nexport const FooterClient: React.FC<FooterClientProps> = ({ data }) => {\n\tconst currentYear = new Date().getFullYear()\n\tconst [email, setEmail] = useState(\"\")\n\tconst [isSubmitting, setIsSubmitting] = useState(false)\n\tconst [message, setMessage] = useState<{ type: \"success\" | \"error\"; text: string } | null>(null)\n\n\tconst { columns, socialLinks, newsletter, copyrightText, bottomLinks } = data\n\n\tconst handleNewsletterSubmit = async (e: React.FormEvent) => {\n\t\te.preventDefault()\n\t\tif (!email || isSubmitting) return\n\n\t\tsetIsSubmitting(true)\n\t\tsetMessage(null)\n\n\t\ttry {\n\t\t\tconst response = await fetch(\"/api/newsletter\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({ email }),\n\t\t\t})\n\n\t\t\tconst result = await response.json()\n\n\t\t\tif (result.success) {\n\t\t\t\tsetMessage({ type: \"success\", text: result.message })\n\t\t\t\tsetEmail(\"\")\n\t\t\t} else {\n\t\t\t\tsetMessage({ type: \"error\", text: result.message })\n\t\t\t}\n\t\t} catch {\n\t\t\tsetMessage({ type: \"error\", text: \"Something went wrong. Please try again.\" })\n\t\t} finally {\n\t\t\tsetIsSubmitting(false)\n\t\t}\n\t}\n\n\t// Check if any social links are configured\n\tconst hasSocialLinks =\n\t\tsocialLinks?.twitter ||\n\t\tsocialLinks?.instagram ||\n\t\tsocialLinks?.linkedin ||\n\t\tsocialLinks?.github ||\n\t\tsocialLinks?.youtube\n\n\treturn (\n\t\t<footer className=\"mt-auto border-t border-border bg-background\">\n\t\t\t{/* Main Footer Content */}\n\t\t\t<div className=\"container mx-auto px-4 py-12 lg:py-16\">\n\t\t\t\t<div className=\"grid grid-cols-2 gap-8 md:grid-cols-3 lg:grid-cols-6\">\n\t\t\t\t\t{/* Link Columns */}\n\t\t\t\t\t{columns?.map((column) => (\n\t\t\t\t\t\t<div key={column.id || column.title} className=\"col-span-1\">\n\t\t\t\t\t\t\t<h3 className=\"mb-4 text-sm font-medium text-foreground\">{column.title}</h3>\n\t\t\t\t\t\t\t<ul className=\"space-y-3\">\n\t\t\t\t\t\t\t\t{column.links?.map((linkItem) => (\n\t\t\t\t\t\t\t\t\t<li key={linkItem.id || linkItem.link.label}>\n\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\thref={getLinkUrl(linkItem.link)}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t{...(linkItem.link.newTab\n\t\t\t\t\t\t\t\t\t\t\t\t? { target: \"_blank\", rel: \"noopener noreferrer\" }\n\t\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{linkItem.link.label}\n\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\n\t\t\t\t\t{/* Newsletter Column */}\n\t\t\t\t\t{newsletter?.enabled && (\n\t\t\t\t\t\t<div className=\"col-span-2 md:col-span-3 lg:col-span-2\">\n\t\t\t\t\t\t\t<h3 className=\"mb-4 text-sm font-medium text-foreground\">\n\t\t\t\t\t\t\t\t{newsletter.title || \"Newsletter\"}\n\t\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t\t<p className=\"mb-4 text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t{newsletter.description || \"Stay up to date with the latest updates.\"}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t\tonSubmit={handleNewsletterSubmit}\n\t\t\t\t\t\t\t\tclassName=\"space-y-3\"\n\t\t\t\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"flex gap-2\">\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\t\tplaceholder={newsletter.placeholder || \"Enter your email\"}\n\t\t\t\t\t\t\t\t\t\tvalue={email}\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => setEmail(e.target.value)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex-1\"\n\t\t\t\t\t\t\t\t\t\tdisabled={isSubmitting}\n\t\t\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<Button type=\"submit\" disabled={isSubmitting} suppressHydrationWarning>\n\t\t\t\t\t\t\t\t\t\t{isSubmitting ? \"...\" : newsletter.buttonText || \"Subscribe\"}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{message && (\n\t\t\t\t\t\t\t\t\t<p\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\"text-sm\",\n\t\t\t\t\t\t\t\t\t\t\tmessage.type === \"success\" ? \"text-green-600\" : \"text-red-600\",\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{message.text}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{/* Social Links */}\n\t\t\t\t{hasSocialLinks && (\n\t\t\t\t\t<div className=\"mt-10 flex items-center gap-4 border-t border-border pt-8\">\n\t\t\t\t\t\t{socialLinks?.twitter && (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={socialLinks.twitter}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\taria-label=\"X (Twitter)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{SocialIcons.twitter}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{socialLinks?.instagram && (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={socialLinks.instagram}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\taria-label=\"Instagram\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{SocialIcons.instagram}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{socialLinks?.linkedin && (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={socialLinks.linkedin}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\taria-label=\"LinkedIn\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{SocialIcons.linkedin}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{socialLinks?.github && (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={socialLinks.github}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\taria-label=\"GitHub\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{SocialIcons.github}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{socialLinks?.youtube && (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={socialLinks.youtube}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\taria-label=\"YouTube\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{SocialIcons.youtube}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{/* Bottom Bar */}\n\t\t\t<div className=\"border-t border-border\">\n\t\t\t\t<div className=\"container mx-auto flex flex-col items-center justify-between gap-4 px-4 py-6 sm:flex-row\">\n\t\t\t\t\t{/* Logo and Copyright */}\n\t\t\t\t\t<div className=\"flex items-center gap-4\">\n\t\t\t\t\t\t<Link href=\"/\" className=\"flex items-center\">\n\t\t\t\t\t\t\t<Logo variant=\"auto\" className=\"h-6 w-6\" />\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t© {currentYear} {copyrightText || \"DirectoryHub\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{/* Bottom Links and Theme Selector */}\n\t\t\t\t\t<div className=\"flex items-center gap-6\">\n\t\t\t\t\t\t{bottomLinks?.map((linkItem) => (\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tkey={linkItem.id || linkItem.link.label}\n\t\t\t\t\t\t\t\thref={getLinkUrl(linkItem.link)}\n\t\t\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t\t\t\t\t\t{...(linkItem.link.newTab ? { target: \"_blank\", rel: \"noopener noreferrer\" } : {})}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{linkItem.link.label}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t<ThemeSelector />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</footer>\n\t)\n}\n",
57
57
  "marketing/payload/src/Footer/Component.tsx": "import { getCachedGlobal } from \"@/utilities/getGlobals\"\n\nimport type { Footer as FooterType } from \"@/payload-types\"\n\nimport { FooterClient } from \"./Component.client\"\n\nexport async function Footer() {\n\tconst footerData: FooterType = await getCachedGlobal(\"footer\", 1)()\n\n\treturn <FooterClient data={footerData} />\n}\n",
@@ -49,6 +49,7 @@
49
49
  "react-dom": "^19.0.0",
50
50
  "react-hook-form": "^7.71.1",
51
51
  "sharp": "^0.34.0",
52
+ "stripe": "^17.7.0",
52
53
  "tailwind-merge": "^3.4.0"
53
54
  },
54
55
  "devDependencies": {