kofi-stack-template-generator 2.1.37 → 2.1.39

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 (323) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/dist/index.js +8057 -440
  3. package/package.json +1 -1
  4. package/src/templates.generated.ts +248 -94
  5. package/templates/integrations/posthog/src/components/providers/posthog-provider.tsx.hbs +4 -1
  6. package/templates/marketing/payload/package.json.hbs +41 -26
  7. package/templates/marketing/payload/src/Footer/Component.client.tsx +288 -0
  8. package/templates/marketing/payload/src/Footer/Component.tsx +11 -0
  9. package/templates/marketing/payload/src/Footer/RowLabel.tsx +15 -0
  10. package/templates/marketing/payload/src/Footer/config.ts +178 -0
  11. package/templates/marketing/payload/src/Footer/hooks/{revalidateFooter.ts.hbs → revalidateFooter.ts} +5 -5
  12. package/templates/marketing/payload/src/Header/Component.client.tsx +94 -0
  13. package/templates/marketing/payload/src/Header/Component.tsx +10 -0
  14. package/templates/marketing/payload/src/Header/MegaMenu/index.tsx +197 -0
  15. package/templates/marketing/payload/src/Header/MobileMenu/HamburgerIcon.tsx +48 -0
  16. package/templates/marketing/payload/src/Header/MobileMenu/index.tsx +299 -0
  17. package/templates/marketing/payload/src/Header/Nav/index.tsx +76 -0
  18. package/templates/marketing/payload/src/Header/RowLabel.tsx +21 -0
  19. package/templates/marketing/payload/src/Header/config.ts +208 -0
  20. package/templates/marketing/payload/src/Header/hooks/{revalidateHeader.ts.hbs → revalidateHeader.ts} +5 -5
  21. package/templates/marketing/payload/src/access/{authenticated.ts.hbs → authenticated.ts} +1 -1
  22. package/templates/marketing/payload/src/access/{authenticatedOrPublished.ts.hbs → authenticatedOrPublished.ts} +8 -8
  23. package/templates/marketing/payload/src/app/(docs)/docs/[[...slug]]/page.tsx +117 -0
  24. package/templates/marketing/payload/src/app/(docs)/docs/layout.tsx +39 -0
  25. package/templates/marketing/payload/src/app/(docs)/layout.tsx +44 -0
  26. package/templates/marketing/payload/src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts +68 -0
  27. package/templates/marketing/payload/src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts +55 -0
  28. package/templates/marketing/payload/src/app/(frontend)/[slug]/page.client.tsx +15 -0
  29. package/templates/marketing/payload/src/app/(frontend)/[slug]/page.tsx +114 -0
  30. package/templates/marketing/payload/src/app/(frontend)/api/docs-search/route.ts +67 -0
  31. package/templates/marketing/payload/src/app/(frontend)/api/newsletter/route.ts +260 -0
  32. package/templates/marketing/payload/src/app/(frontend)/api/pricing/route.ts +266 -0
  33. package/templates/marketing/payload/src/app/(frontend)/globals.css +1019 -0
  34. package/templates/marketing/payload/src/app/(frontend)/layout.tsx +114 -0
  35. package/templates/marketing/payload/src/app/(frontend)/next/exit-preview/route.ts +7 -0
  36. package/templates/marketing/payload/src/app/(frontend)/next/preview/route.ts +56 -0
  37. package/templates/marketing/payload/src/app/(frontend)/next/seed/route.ts +31 -0
  38. package/templates/marketing/payload/src/app/(frontend)/not-found.tsx +17 -0
  39. package/templates/marketing/payload/src/app/(frontend)/page.tsx +5 -0
  40. package/templates/marketing/payload/src/app/(frontend)/posts/BlogPageClient.tsx +190 -0
  41. package/templates/marketing/payload/src/app/(frontend)/posts/[slug]/BlogPostContent.tsx +67 -0
  42. package/templates/marketing/payload/src/app/(frontend)/posts/[slug]/page.client.tsx +15 -0
  43. package/templates/marketing/payload/src/app/(frontend)/posts/[slug]/page.tsx +118 -0
  44. package/templates/marketing/payload/src/app/(frontend)/posts/page/[pageNumber]/page.client.tsx +15 -0
  45. package/templates/marketing/payload/src/app/(frontend)/posts/page/[pageNumber]/page.tsx +87 -0
  46. package/templates/marketing/payload/src/app/(frontend)/posts/page.tsx +49 -0
  47. package/templates/marketing/payload/src/app/(frontend)/search/page.client.tsx +15 -0
  48. package/templates/marketing/payload/src/app/(frontend)/search/page.tsx +87 -0
  49. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/not-found.tsx +24 -0
  50. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/page.tsx +24 -0
  51. package/templates/marketing/payload/src/app/(payload)/admin/importMap.js +83 -0
  52. package/templates/marketing/payload/src/app/(payload)/api/[...slug]/{route.ts.hbs → route.ts} +13 -9
  53. package/templates/marketing/payload/src/app/(payload)/api/graphql/{route.ts.hbs → route.ts} +2 -2
  54. package/templates/marketing/payload/src/app/(payload)/api/graphql-playground/{route.ts.hbs → route.ts} +3 -3
  55. package/templates/marketing/payload/src/app/(payload)/custom.scss +0 -0
  56. package/templates/marketing/payload/src/app/(payload)/layout.tsx +31 -0
  57. package/templates/marketing/payload/src/blocks/ArchiveBlock/Component.tsx +65 -0
  58. package/templates/marketing/payload/src/blocks/ArchiveBlock/config.ts +120 -0
  59. package/templates/marketing/payload/src/blocks/Banner/Component.tsx +26 -0
  60. package/templates/marketing/payload/src/blocks/Banner/config.ts +67 -0
  61. package/templates/marketing/payload/src/blocks/BentoFeatures/Component.tsx +243 -0
  62. package/templates/marketing/payload/src/blocks/BentoFeatures/config.ts +147 -0
  63. package/templates/marketing/payload/src/blocks/CallToAction/Component.tsx +31 -0
  64. package/templates/marketing/payload/src/blocks/CallToAction/config.ts +68 -0
  65. package/templates/marketing/payload/src/blocks/Code/Component.client.tsx +33 -0
  66. package/templates/marketing/payload/src/blocks/Code/Component.tsx +21 -0
  67. package/templates/marketing/payload/src/blocks/Code/CopyButton.tsx +33 -0
  68. package/templates/marketing/payload/src/blocks/Code/config.ts +33 -0
  69. package/templates/marketing/payload/src/blocks/Content/Component.tsx +41 -0
  70. package/templates/marketing/payload/src/blocks/Content/config.ts +105 -0
  71. package/templates/marketing/payload/src/blocks/FAQAccordion/Component.tsx +90 -0
  72. package/templates/marketing/payload/src/blocks/FAQAccordion/config.ts +75 -0
  73. package/templates/marketing/payload/src/blocks/FeatureGrid/Component.tsx +124 -0
  74. package/templates/marketing/payload/src/blocks/FeatureGrid/config.ts +120 -0
  75. package/templates/marketing/payload/src/blocks/FeatureShowcase/Component.tsx +107 -0
  76. package/templates/marketing/payload/src/blocks/FeatureShowcase/config.ts +111 -0
  77. package/templates/marketing/payload/src/blocks/FinalCTA/Component.tsx +117 -0
  78. package/templates/marketing/payload/src/blocks/FinalCTA/config.ts +50 -0
  79. package/templates/marketing/payload/src/blocks/Form/Checkbox/index.tsx +45 -0
  80. package/templates/marketing/payload/src/blocks/Form/Component.tsx +170 -0
  81. package/templates/marketing/payload/src/blocks/Form/Country/index.tsx +65 -0
  82. package/templates/marketing/payload/src/blocks/Form/Country/options.ts +982 -0
  83. package/templates/marketing/payload/src/blocks/Form/Email/index.tsx +38 -0
  84. package/templates/marketing/payload/src/blocks/Form/Error/index.tsx +13 -0
  85. package/templates/marketing/payload/src/blocks/Form/Message/index.tsx +13 -0
  86. package/templates/marketing/payload/src/blocks/Form/Number/index.tsx +36 -0
  87. package/templates/marketing/payload/src/blocks/Form/Select/index.tsx +63 -0
  88. package/templates/marketing/payload/src/blocks/Form/State/index.tsx +64 -0
  89. package/templates/marketing/payload/src/blocks/Form/State/options.ts +52 -0
  90. package/templates/marketing/payload/src/blocks/Form/Text/index.tsx +32 -0
  91. package/templates/marketing/payload/src/blocks/Form/Textarea/index.tsx +40 -0
  92. package/templates/marketing/payload/src/blocks/Form/Width/index.tsx +13 -0
  93. package/templates/marketing/payload/src/blocks/Form/config.ts +77 -0
  94. package/templates/marketing/payload/src/blocks/Form/fields.tsx +21 -0
  95. package/templates/marketing/payload/src/blocks/HowItWorks/Component.tsx +59 -0
  96. package/templates/marketing/payload/src/blocks/HowItWorks/config.ts +88 -0
  97. package/templates/marketing/payload/src/blocks/IndustryTabs/Component.tsx +132 -0
  98. package/templates/marketing/payload/src/blocks/IndustryTabs/config.ts +77 -0
  99. package/templates/marketing/payload/src/blocks/LogoBanner/Component.tsx +95 -0
  100. package/templates/marketing/payload/src/blocks/LogoBanner/config.ts +48 -0
  101. package/templates/marketing/payload/src/blocks/MediaBlock/Component.tsx +67 -0
  102. package/templates/marketing/payload/src/blocks/MediaBlock/config.ts +14 -0
  103. package/templates/marketing/payload/src/blocks/Personas/Component.tsx +69 -0
  104. package/templates/marketing/payload/src/blocks/Personas/config.ts +96 -0
  105. package/templates/marketing/payload/src/blocks/PricingTable/ComparisonTable.tsx +250 -0
  106. package/templates/marketing/payload/src/blocks/PricingTable/Component.tsx +443 -0
  107. package/templates/marketing/payload/src/blocks/PricingTable/config.ts +142 -0
  108. package/templates/marketing/payload/src/blocks/ProofBanner/Component.tsx +65 -0
  109. package/templates/marketing/payload/src/blocks/ProofBanner/config.ts +42 -0
  110. package/templates/marketing/payload/src/blocks/RelatedPosts/Component.tsx +32 -0
  111. package/templates/marketing/payload/src/blocks/RenderBlocks.tsx +92 -0
  112. package/templates/marketing/payload/src/blocks/TestimonialsGrid/Component.tsx +107 -0
  113. package/templates/marketing/payload/src/blocks/TestimonialsGrid/config.ts +76 -0
  114. package/templates/marketing/payload/src/blocks/TrustColumns/Component.tsx +83 -0
  115. package/templates/marketing/payload/src/blocks/TrustColumns/config.ts +70 -0
  116. package/templates/marketing/payload/src/collections/Categories.ts +28 -0
  117. package/templates/marketing/payload/src/collections/FAQs/index.ts +100 -0
  118. package/templates/marketing/payload/src/collections/Media.ts +160 -0
  119. package/templates/marketing/payload/src/collections/Pages/hooks/revalidatePage.ts +43 -0
  120. package/templates/marketing/payload/src/collections/Pages/index.ts +168 -0
  121. package/templates/marketing/payload/src/collections/Posts/hooks/populateAuthors.ts +41 -0
  122. package/templates/marketing/payload/src/collections/Posts/hooks/revalidatePost.ts +44 -0
  123. package/templates/marketing/payload/src/collections/Posts/index.ts +259 -0
  124. package/templates/marketing/payload/src/collections/Users/index.ts +26 -0
  125. package/templates/marketing/payload/src/components/AdminBar/index.scss +7 -0
  126. package/templates/marketing/payload/src/components/AdminBar/index.tsx +89 -0
  127. package/templates/marketing/payload/src/components/Analytics/CTATracker.tsx +33 -0
  128. package/templates/marketing/payload/src/components/Analytics/FeatureSectionTracker.tsx +47 -0
  129. package/templates/marketing/payload/src/components/Analytics/PricingViewTracker.tsx +46 -0
  130. package/templates/marketing/payload/src/components/Analytics/index.tsx +3 -0
  131. package/templates/marketing/payload/src/components/BeforeDashboard/SeedButton/index.tsx +89 -0
  132. package/templates/marketing/payload/src/components/BeforeDashboard/index.tsx +69 -0
  133. package/templates/marketing/payload/src/components/BeforeLogin/index.tsx +14 -0
  134. package/templates/marketing/payload/src/components/BlogCTA/index.tsx +77 -0
  135. package/templates/marketing/payload/src/components/Card/index.tsx +85 -0
  136. package/templates/marketing/payload/src/components/CollectionArchive/index.tsx +32 -0
  137. package/templates/marketing/payload/src/components/JsonLd/index.tsx +138 -0
  138. package/templates/marketing/payload/src/components/Link/index.tsx +66 -0
  139. package/templates/marketing/payload/src/components/LivePreviewListener/index.tsx +10 -0
  140. package/templates/marketing/payload/src/components/Logo/Logo.tsx +46 -0
  141. package/templates/marketing/payload/src/components/Media/ImageMedia/index.tsx +80 -0
  142. package/templates/marketing/payload/src/components/Media/VideoMedia/index.tsx +47 -0
  143. package/templates/marketing/payload/src/components/Media/index.tsx +26 -0
  144. package/templates/marketing/payload/src/components/Media/types.ts +22 -0
  145. package/templates/marketing/payload/src/components/PageRange/index.tsx +57 -0
  146. package/templates/marketing/payload/src/components/Pagination/index.tsx +101 -0
  147. package/templates/marketing/payload/src/components/PayloadRedirects/index.tsx +48 -0
  148. package/templates/marketing/payload/src/components/RichText/index.tsx +152 -0
  149. package/templates/marketing/payload/src/components/TableOfContents/index.tsx +128 -0
  150. package/templates/marketing/payload/src/components/ui/accordion.tsx +64 -0
  151. package/templates/marketing/payload/src/components/ui/button.tsx +52 -0
  152. package/templates/marketing/payload/src/components/ui/card.tsx +48 -0
  153. package/templates/marketing/payload/src/components/ui/checkbox.tsx +27 -0
  154. package/templates/marketing/payload/src/components/ui/input.tsx +22 -0
  155. package/templates/marketing/payload/src/components/ui/label.tsx +19 -0
  156. package/templates/marketing/payload/src/components/ui/pagination.tsx +92 -0
  157. package/templates/marketing/payload/src/components/ui/select.tsx +144 -0
  158. package/templates/marketing/payload/src/components/ui/textarea.tsx +21 -0
  159. package/templates/marketing/payload/src/endpoints/seed/contact-form.ts +111 -0
  160. package/templates/marketing/payload/src/endpoints/seed/contact-page.ts +56 -0
  161. package/templates/marketing/payload/src/endpoints/seed/directoryhub/about.ts +281 -0
  162. package/templates/marketing/payload/src/endpoints/seed/directoryhub/faqs.ts +224 -0
  163. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/automation.ts +229 -0
  164. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/custom-fields.ts +229 -0
  165. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/dashboard.ts +228 -0
  166. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/index.ts +6 -0
  167. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/monetization.ts +230 -0
  168. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/seo.ts +229 -0
  169. package/templates/marketing/payload/src/endpoints/seed/directoryhub/features/templates.ts +218 -0
  170. package/templates/marketing/payload/src/endpoints/seed/directoryhub/home.ts +555 -0
  171. package/templates/marketing/payload/src/endpoints/seed/directoryhub/index.ts +767 -0
  172. package/templates/marketing/payload/src/endpoints/seed/directoryhub/posts.ts +623 -0
  173. package/templates/marketing/payload/src/endpoints/seed/directoryhub/pricing.ts +251 -0
  174. package/templates/marketing/payload/src/endpoints/seed/directoryhub/privacy.ts +457 -0
  175. package/templates/marketing/payload/src/endpoints/seed/directoryhub/richtext-helper.ts +88 -0
  176. package/templates/marketing/payload/src/endpoints/seed/directoryhub/terms.ts +478 -0
  177. package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/b2b-vendor-hubs.ts +229 -0
  178. package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/communities.ts +230 -0
  179. package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/index.ts +4 -0
  180. package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/local-services.ts +230 -0
  181. package/templates/marketing/payload/src/endpoints/seed/directoryhub/use-cases/marketplaces.ts +230 -0
  182. package/templates/marketing/payload/src/endpoints/seed/home-static.ts +691 -0
  183. package/templates/marketing/payload/src/endpoints/seed/home.ts +675 -0
  184. package/templates/marketing/payload/src/endpoints/seed/image-1.ts +67 -0
  185. package/templates/marketing/payload/src/endpoints/seed/image-2.ts +67 -0
  186. package/templates/marketing/payload/src/endpoints/seed/image-3.ts +67 -0
  187. package/templates/marketing/payload/src/endpoints/seed/image-hero-1.ts +5 -0
  188. package/templates/marketing/payload/src/endpoints/seed/image-hero1.webp +0 -0
  189. package/templates/marketing/payload/src/endpoints/seed/image-post1.webp +0 -0
  190. package/templates/marketing/payload/src/endpoints/seed/image-post2.webp +0 -0
  191. package/templates/marketing/payload/src/endpoints/seed/image-post3.webp +0 -0
  192. package/templates/marketing/payload/src/endpoints/seed/index.ts +335 -0
  193. package/templates/marketing/payload/src/endpoints/seed/post-1.ts +315 -0
  194. package/templates/marketing/payload/src/endpoints/seed/post-2.ts +232 -0
  195. package/templates/marketing/payload/src/endpoints/seed/post-3.ts +268 -0
  196. package/templates/marketing/payload/src/fields/defaultLexical.ts +73 -0
  197. package/templates/marketing/payload/src/fields/link.ts +139 -0
  198. package/templates/marketing/payload/src/fields/linkGroup.ts +28 -0
  199. package/templates/marketing/payload/src/heros/HighImpact/index.tsx +56 -0
  200. package/templates/marketing/payload/src/heros/LowImpact/index.tsx +48 -0
  201. package/templates/marketing/payload/src/heros/MediumImpact/index.tsx +50 -0
  202. package/templates/marketing/payload/src/heros/PostHero/index.tsx +73 -0
  203. package/templates/marketing/payload/src/heros/ProductShowcase/AnimatedMockup.tsx +241 -0
  204. package/templates/marketing/payload/src/heros/ProductShowcase/index.tsx +108 -0
  205. package/templates/marketing/payload/src/heros/{RenderHero.tsx.hbs → RenderHero.tsx} +9 -9
  206. package/templates/marketing/payload/src/heros/config.ts +121 -0
  207. package/templates/marketing/payload/src/hooks/populatePublishedAt.ts +15 -0
  208. package/templates/marketing/payload/src/hooks/{revalidateRedirects.ts.hbs → revalidateRedirects.ts} +3 -3
  209. package/templates/marketing/payload/src/lib/convex.ts +13 -0
  210. package/templates/marketing/payload/src/lib/docs-source.ts +138 -0
  211. package/templates/marketing/payload/src/lib/mdx.tsx +191 -0
  212. package/templates/marketing/payload/src/payload.config.ts.hbs +95 -145
  213. package/templates/marketing/payload/src/plugins/index.ts +107 -0
  214. package/templates/marketing/payload/src/providers/HeaderTheme/index.tsx +34 -0
  215. package/templates/marketing/payload/src/providers/PostHogProvider.tsx +33 -0
  216. package/templates/marketing/payload/src/providers/Theme/InitTheme/{index.tsx.hbs → index.tsx} +11 -10
  217. package/templates/marketing/payload/src/providers/Theme/ThemeSelector/index.tsx +133 -0
  218. package/templates/marketing/payload/src/providers/Theme/ThemeSelector/types.ts +7 -0
  219. package/templates/marketing/payload/src/providers/Theme/index.tsx +60 -0
  220. package/templates/marketing/payload/src/providers/Theme/shared.ts +17 -0
  221. package/templates/marketing/payload/src/providers/Theme/{types.ts.hbs → types.ts} +3 -3
  222. package/templates/marketing/payload/src/providers/index.tsx +17 -0
  223. package/templates/marketing/payload/src/search/Component.tsx +42 -0
  224. package/templates/marketing/payload/src/search/beforeSync.ts +56 -0
  225. package/templates/marketing/payload/src/search/fieldOverrides.ts +61 -0
  226. package/templates/marketing/payload/src/utilities/deepMerge.ts +35 -0
  227. package/templates/marketing/payload/src/utilities/extractHeadings.ts +78 -0
  228. package/templates/marketing/payload/src/utilities/formatAuthors.ts +24 -0
  229. package/templates/marketing/payload/src/utilities/formatDateTime.ts +20 -0
  230. package/templates/marketing/payload/src/utilities/generateMeta.ts +93 -0
  231. package/templates/marketing/payload/src/utilities/generatePreviewPath.ts +33 -0
  232. package/templates/marketing/payload/src/utilities/getDocument.ts +32 -0
  233. package/templates/marketing/payload/src/utilities/getGlobals.ts +26 -0
  234. package/templates/marketing/payload/src/utilities/getMeUser.ts +43 -0
  235. package/templates/marketing/payload/src/utilities/getMediaUrl.ts +24 -0
  236. package/templates/marketing/payload/src/utilities/getRedirects.ts +26 -0
  237. package/templates/marketing/payload/src/utilities/getURL.ts +26 -0
  238. package/templates/marketing/payload/src/utilities/mergeOpenGraph.ts +26 -0
  239. package/templates/marketing/payload/src/utilities/toKebabCase.ts +5 -0
  240. package/templates/marketing/payload/src/utilities/ui.ts +12 -0
  241. package/templates/marketing/payload/src/utilities/useClickableCard.ts +108 -0
  242. package/templates/marketing/payload/src/utilities/useDebounce.ts +17 -0
  243. package/templates/packages/ui/src/components/button.tsx.hbs +53 -0
  244. package/templates/packages/ui/src/components/card.tsx.hbs +76 -0
  245. package/templates/packages/ui/src/components/separator.tsx.hbs +26 -0
  246. package/templates/marketing/payload/src/Footer/config.ts.hbs +0 -178
  247. package/templates/marketing/payload/src/Footer/index.ts.hbs +0 -1
  248. package/templates/marketing/payload/src/Header/RowLabel.tsx.hbs +0 -21
  249. package/templates/marketing/payload/src/Header/config.ts.hbs +0 -208
  250. package/templates/marketing/payload/src/Header/index.ts.hbs +0 -1
  251. package/templates/marketing/payload/src/access/index.ts.hbs +0 -3
  252. package/templates/marketing/payload/src/app/(frontend)/layout.tsx.hbs +0 -19
  253. package/templates/marketing/payload/src/app/(frontend)/next/seed/route.ts.hbs +0 -31
  254. package/templates/marketing/payload/src/app/(frontend)/page.tsx.hbs +0 -83
  255. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/not-found.tsx.hbs +0 -24
  256. package/templates/marketing/payload/src/app/(payload)/admin/[[...segments]]/page.tsx.hbs +0 -24
  257. package/templates/marketing/payload/src/app/(payload)/admin/importMap.js.hbs +0 -1
  258. package/templates/marketing/payload/src/app/(payload)/custom.scss.hbs +0 -1
  259. package/templates/marketing/payload/src/app/(payload)/layout.tsx.hbs +0 -31
  260. package/templates/marketing/payload/src/app/globals.css.hbs +0 -83
  261. package/templates/marketing/payload/src/app/layout.tsx.hbs +0 -10
  262. package/templates/marketing/payload/src/blocks/Benefits.ts.hbs +0 -34
  263. package/templates/marketing/payload/src/blocks/CTA.ts.hbs +0 -39
  264. package/templates/marketing/payload/src/blocks/Content.ts.hbs +0 -9
  265. package/templates/marketing/payload/src/blocks/FAQ.ts.hbs +0 -18
  266. package/templates/marketing/payload/src/blocks/Features.ts.hbs +0 -34
  267. package/templates/marketing/payload/src/blocks/Hero.ts.hbs +0 -40
  268. package/templates/marketing/payload/src/blocks/LogoBanner.ts.hbs +0 -17
  269. package/templates/marketing/payload/src/blocks/Pricing.ts.hbs +0 -37
  270. package/templates/marketing/payload/src/blocks/Testimonials.ts.hbs +0 -21
  271. package/templates/marketing/payload/src/blocks/index.ts.hbs +0 -9
  272. package/templates/marketing/payload/src/collections/Categories/index.ts.hbs +0 -28
  273. package/templates/marketing/payload/src/collections/FAQs/index.ts.hbs +0 -100
  274. package/templates/marketing/payload/src/collections/Media.ts.hbs +0 -164
  275. package/templates/marketing/payload/src/collections/Pages/hooks/revalidatePage.ts.hbs +0 -43
  276. package/templates/marketing/payload/src/collections/Pages/index.ts.hbs +0 -142
  277. package/templates/marketing/payload/src/collections/Posts/hooks/populateAuthors.ts.hbs +0 -41
  278. package/templates/marketing/payload/src/collections/Posts/hooks/revalidatePost.ts.hbs +0 -44
  279. package/templates/marketing/payload/src/collections/Posts/index.ts.hbs +0 -244
  280. package/templates/marketing/payload/src/collections/Users/index.ts.hbs +0 -26
  281. package/templates/marketing/payload/src/collections/index.ts.hbs +0 -6
  282. package/templates/marketing/payload/src/components/BeforeDashboard/SeedButton/index.tsx.hbs +0 -89
  283. package/templates/marketing/payload/src/components/BeforeDashboard/index.tsx.hbs +0 -69
  284. package/templates/marketing/payload/src/components/BeforeLogin/index.tsx.hbs +0 -14
  285. package/templates/marketing/payload/src/components/Link/index.tsx.hbs +0 -79
  286. package/templates/marketing/payload/src/components/Media/index.tsx.hbs +0 -67
  287. package/templates/marketing/payload/src/components/RichText/index.tsx.hbs +0 -44
  288. package/templates/marketing/payload/src/endpoints/seed/home.ts.hbs +0 -76
  289. package/templates/marketing/payload/src/endpoints/seed/image-1.ts.hbs +0 -5
  290. package/templates/marketing/payload/src/endpoints/seed/image-2.ts.hbs +0 -5
  291. package/templates/marketing/payload/src/endpoints/seed/image-hero.ts.hbs +0 -5
  292. package/templates/marketing/payload/src/endpoints/seed/index.ts.hbs +0 -235
  293. package/templates/marketing/payload/src/endpoints/seed/post-1.ts.hbs +0 -252
  294. package/templates/marketing/payload/src/fields/defaultLexical.ts.hbs +0 -73
  295. package/templates/marketing/payload/src/fields/link.ts.hbs +0 -139
  296. package/templates/marketing/payload/src/fields/linkGroup.ts.hbs +0 -28
  297. package/templates/marketing/payload/src/globals/index.ts.hbs +0 -2
  298. package/templates/marketing/payload/src/heros/HighImpact/index.tsx.hbs +0 -53
  299. package/templates/marketing/payload/src/heros/LowImpact/index.tsx.hbs +0 -48
  300. package/templates/marketing/payload/src/heros/MediumImpact/index.tsx.hbs +0 -46
  301. package/templates/marketing/payload/src/heros/PostHero/index.tsx.hbs +0 -68
  302. package/templates/marketing/payload/src/heros/ProductShowcase/index.tsx.hbs +0 -88
  303. package/templates/marketing/payload/src/heros/config.ts.hbs +0 -112
  304. package/templates/marketing/payload/src/heros/index.ts.hbs +0 -7
  305. package/templates/marketing/payload/src/hooks/index.ts.hbs +0 -2
  306. package/templates/marketing/payload/src/hooks/populatePublishedAt.ts.hbs +0 -15
  307. package/templates/marketing/payload/src/providers/HeaderTheme/index.tsx.hbs +0 -34
  308. package/templates/marketing/payload/src/providers/Theme/index.tsx.hbs +0 -60
  309. package/templates/marketing/payload/src/providers/Theme/shared.ts.hbs +0 -17
  310. package/templates/marketing/payload/src/providers/index.tsx.hbs +0 -18
  311. package/templates/marketing/payload/src/utilities/deepMerge.ts.hbs +0 -35
  312. package/templates/marketing/payload/src/utilities/formatAuthors.ts.hbs +0 -24
  313. package/templates/marketing/payload/src/utilities/formatDateTime.ts.hbs +0 -13
  314. package/templates/marketing/payload/src/utilities/generateMeta.ts.hbs +0 -87
  315. package/templates/marketing/payload/src/utilities/generatePreviewPath.ts.hbs +0 -33
  316. package/templates/marketing/payload/src/utilities/getURL.ts.hbs +0 -26
  317. package/templates/marketing/payload/src/utilities/index.ts.hbs +0 -8
  318. package/templates/marketing/payload/src/utilities/mergeOpenGraph.ts.hbs +0 -26
  319. /package/templates/marketing/payload/src/access/{anyone.ts.hbs → anyone.ts} +0 -0
  320. /package/templates/marketing/payload/src/components/BeforeDashboard/SeedButton/{index.scss.hbs → index.scss} +0 -0
  321. /package/templates/marketing/payload/src/components/BeforeDashboard/{index.scss.hbs → index.scss} +0 -0
  322. /package/templates/marketing/payload/src/fields/{index.ts.hbs → index.ts} +0 -0
  323. /package/templates/marketing/payload/src/utilities/{canUseDOM.ts.hbs → canUseDOM.ts} +0 -0
@@ -6,7 +6,10 @@ import { useEffect } from 'react'
6
6
 
7
7
  export function PostHogProvider({ children }: { children: React.ReactNode }) {
8
8
  useEffect(() => {
9
- posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
9
+ const key = process.env.NEXT_PUBLIC_POSTHOG_KEY
10
+ if (!key) return
11
+
12
+ posthog.init(key, {
10
13
  api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',
11
14
  person_profiles: 'identified_only',
12
15
  capture_pageview: false, // We capture pageviews manually
@@ -2,51 +2,66 @@
2
2
  "name": "@repo/marketing",
3
3
  "version": "0.1.0",
4
4
  "private": true,
5
+ "type": "module",
5
6
  "scripts": {
6
- "dev": "next dev --port 3000",
7
- "build": "next build",
8
- "start": "next start",
7
+ "build": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap && next build",
8
+ "dev": "cross-env NODE_OPTIONS=--no-deprecation next dev --port 3000",
9
+ "generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
10
+ "generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
9
11
  "lint": "biome check .",
10
12
  "lint:fix": "biome check --write .",
13
+ "payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
14
+ "start": "cross-env NODE_OPTIONS=--no-deprecation next start",
11
15
  "typecheck": "tsc --noEmit",
12
16
  "db:push": "payload migrate",
13
17
  "db:seed": "tsx src/seed.ts"
14
18
  },
15
19
  "dependencies": {
16
- "next": "^15.4.10",
17
- "react": "^19.0.0",
18
- "react-dom": "^19.0.0",
19
- "payload": "^3.70.0",
20
+ "@payloadcms/admin-bar": "^3.0.0",
20
21
  "@payloadcms/db-postgres": "^3.0.0",
21
- "@payloadcms/next": "^3.0.0",
22
- "@payloadcms/richtext-lexical": "^3.0.0",
23
22
  "@payloadcms/email-resend": "^3.0.0",
23
+ "@payloadcms/live-preview-react": "^3.0.0",
24
+ "@payloadcms/next": "^3.0.0",
25
+ "@payloadcms/plugin-form-builder": "^3.0.0",
26
+ "@payloadcms/plugin-nested-docs": "^3.0.0",
27
+ "@payloadcms/plugin-redirects": "^3.0.0",
28
+ "@payloadcms/plugin-search": "^3.0.0",
24
29
  "@payloadcms/plugin-seo": "^3.0.0",
25
- {{#if (eq integrations.payloadStorage 's3')}}
26
- "@payloadcms/storage-s3": "^3.0.0",
27
- {{/if}}
28
- {{#if (eq integrations.payloadStorage 'r2')}}
29
- "@payloadcms/storage-s3": "^3.0.0",
30
- {{/if}}
31
- {{#if (eq integrations.payloadStorage 'vercel-blob')}}
30
+ "@payloadcms/richtext-lexical": "^3.0.0",
32
31
  "@payloadcms/storage-vercel-blob": "^3.0.0",
33
- {{/if}}
34
- {{#if (eq integrations.payloadStorage 'gcs')}}
35
- "@payloadcms/storage-gcs": "^3.0.0",
36
- {{/if}}
37
- "sharp": "^0.33.0",
38
- "@repo/ui": "workspace:*"
32
+ "@payloadcms/ui": "^3.0.0",
33
+ "@radix-ui/react-accordion": "^1.2.0",
34
+ "@radix-ui/react-checkbox": "^1.0.4",
35
+ "@radix-ui/react-label": "^2.0.2",
36
+ "@radix-ui/react-select": "^2.0.0",
37
+ "@radix-ui/react-slot": "^1.0.2",
38
+ "@repo/ui": "workspace:*",
39
+ "class-variance-authority": "^0.7.1",
40
+ "clsx": "^2.1.1",
41
+ "cross-env": "^7.0.3",
42
+ "lucide-react": "^0.562.0",
43
+ "next": "^15.4.10",
44
+ "payload": "^3.70.0",
45
+ "posthog-js": "^1.200.0",
46
+ "prism-react-renderer": "^2.4.1",
47
+ "react": "^19.0.0",
48
+ "react-dom": "^19.0.0",
49
+ "react-hook-form": "^7.71.1",
50
+ "sharp": "^0.34.0",
51
+ "tailwind-merge": "^3.4.0"
39
52
  },
40
53
  "devDependencies": {
41
54
  "@repo/config-typescript": "workspace:*",
55
+ "@tailwindcss/postcss": "^4.0.0",
56
+ "@tailwindcss/typography": "^0.5.19",
42
57
  "@types/node": "^20.0.0",
43
58
  "@types/react": "^19.0.0",
44
59
  "@types/react-dom": "^19.0.0",
45
- "tailwindcss": "^4.0.0",
46
- "@tailwindcss/postcss": "^4.0.0",
47
60
  "postcss": "^8.4.0",
48
61
  "sass": "^1.86.0",
49
- "typescript": "^5.0.0",
50
- "tsx": "^4.0.0"
62
+ "tailwindcss": "^4.0.0",
63
+ "tsx": "^4.0.0",
64
+ "tw-animate-css": "^1.4.0",
65
+ "typescript": "^5.0.0"
51
66
  }
52
67
  }
@@ -0,0 +1,288 @@
1
+ "use client"
2
+
3
+ import Link from "next/link"
4
+ import type React from "react"
5
+ import { useState } from "react"
6
+
7
+ import type { Footer, Page, Post } from "@/payload-types"
8
+
9
+ import { Logo } from "@/components/Logo/Logo"
10
+ import { Button } from "@/components/ui/button"
11
+ import { Input } from "@/components/ui/input"
12
+ import { ThemeSelector } from "@/providers/Theme/ThemeSelector"
13
+ import { cn } from "@/utilities/ui"
14
+
15
+ interface FooterClientProps {
16
+ data: Footer
17
+ }
18
+
19
+ // Social icons as inline SVGs for flexibility
20
+ const SocialIcons = {
21
+ twitter: (
22
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
23
+ <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" />
24
+ </svg>
25
+ ),
26
+ instagram: (
27
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
28
+ <path
29
+ fillRule="evenodd"
30
+ 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"
31
+ clipRule="evenodd"
32
+ />
33
+ </svg>
34
+ ),
35
+ linkedin: (
36
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
37
+ <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" />
38
+ </svg>
39
+ ),
40
+ github: (
41
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
42
+ <path
43
+ fillRule="evenodd"
44
+ 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"
45
+ clipRule="evenodd"
46
+ />
47
+ </svg>
48
+ ),
49
+ youtube: (
50
+ <svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
51
+ <path
52
+ fillRule="evenodd"
53
+ 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"
54
+ clipRule="evenodd"
55
+ />
56
+ </svg>
57
+ ),
58
+ }
59
+
60
+ // Helper function to get URL from link
61
+ function getLinkUrl(link: {
62
+ type?: ("reference" | "custom") | null
63
+ reference?:
64
+ | { relationTo: "pages"; value: number | Page }
65
+ | { relationTo: "posts"; value: number | Post }
66
+ | null
67
+ url?: string | null
68
+ }): string {
69
+ if (link.type === "reference" && link.reference) {
70
+ const value = link.reference.value
71
+ if (typeof value === "object" && "slug" in value) {
72
+ const prefix = link.reference.relationTo === "posts" ? "/posts" : ""
73
+ return `${prefix}/${value.slug}`
74
+ }
75
+ }
76
+ return link.url || "#"
77
+ }
78
+
79
+ export const FooterClient: React.FC<FooterClientProps> = ({ data }) => {
80
+ const currentYear = new Date().getFullYear()
81
+ const [email, setEmail] = useState("")
82
+ const [isSubmitting, setIsSubmitting] = useState(false)
83
+ const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null)
84
+
85
+ const { columns, socialLinks, newsletter, copyrightText, bottomLinks } = data
86
+
87
+ const handleNewsletterSubmit = async (e: React.FormEvent) => {
88
+ e.preventDefault()
89
+ if (!email || isSubmitting) return
90
+
91
+ setIsSubmitting(true)
92
+ setMessage(null)
93
+
94
+ try {
95
+ const response = await fetch("/api/newsletter", {
96
+ method: "POST",
97
+ headers: { "Content-Type": "application/json" },
98
+ body: JSON.stringify({ email }),
99
+ })
100
+
101
+ const result = await response.json()
102
+
103
+ if (result.success) {
104
+ setMessage({ type: "success", text: result.message })
105
+ setEmail("")
106
+ } else {
107
+ setMessage({ type: "error", text: result.message })
108
+ }
109
+ } catch {
110
+ setMessage({ type: "error", text: "Something went wrong. Please try again." })
111
+ } finally {
112
+ setIsSubmitting(false)
113
+ }
114
+ }
115
+
116
+ // Check if any social links are configured
117
+ const hasSocialLinks =
118
+ socialLinks?.twitter ||
119
+ socialLinks?.instagram ||
120
+ socialLinks?.linkedin ||
121
+ socialLinks?.github ||
122
+ socialLinks?.youtube
123
+
124
+ return (
125
+ <footer className="mt-auto border-t border-border bg-background">
126
+ {/* Main Footer Content */}
127
+ <div className="container mx-auto px-4 py-12 lg:py-16">
128
+ <div className="grid grid-cols-2 gap-8 md:grid-cols-3 lg:grid-cols-6">
129
+ {/* Link Columns */}
130
+ {columns?.map((column) => (
131
+ <div key={column.id || column.title} className="col-span-1">
132
+ <h3 className="mb-4 text-sm font-medium text-foreground">{column.title}</h3>
133
+ <ul className="space-y-3">
134
+ {column.links?.map((linkItem) => (
135
+ <li key={linkItem.id || linkItem.link.label}>
136
+ <Link
137
+ href={getLinkUrl(linkItem.link)}
138
+ className="text-sm text-muted-foreground transition-colors hover:text-foreground"
139
+ {...(linkItem.link.newTab
140
+ ? { target: "_blank", rel: "noopener noreferrer" }
141
+ : {})}
142
+ >
143
+ {linkItem.link.label}
144
+ </Link>
145
+ </li>
146
+ ))}
147
+ </ul>
148
+ </div>
149
+ ))}
150
+
151
+ {/* Newsletter Column */}
152
+ {newsletter?.enabled && (
153
+ <div className="col-span-2 md:col-span-3 lg:col-span-2">
154
+ <h3 className="mb-4 text-sm font-medium text-foreground">
155
+ {newsletter.title || "Newsletter"}
156
+ </h3>
157
+ <p className="mb-4 text-sm text-muted-foreground">
158
+ {newsletter.description || "Stay up to date with the latest updates."}
159
+ </p>
160
+ <form
161
+ onSubmit={handleNewsletterSubmit}
162
+ className="space-y-3"
163
+ suppressHydrationWarning
164
+ >
165
+ <div className="flex gap-2">
166
+ <Input
167
+ type="email"
168
+ placeholder={newsletter.placeholder || "Enter your email"}
169
+ value={email}
170
+ onChange={(e) => setEmail(e.target.value)}
171
+ className="flex-1"
172
+ disabled={isSubmitting}
173
+ required
174
+ suppressHydrationWarning
175
+ />
176
+ <Button type="submit" disabled={isSubmitting} suppressHydrationWarning>
177
+ {isSubmitting ? "..." : newsletter.buttonText || "Subscribe"}
178
+ </Button>
179
+ </div>
180
+ {message && (
181
+ <p
182
+ className={cn(
183
+ "text-sm",
184
+ message.type === "success" ? "text-green-600" : "text-red-600",
185
+ )}
186
+ >
187
+ {message.text}
188
+ </p>
189
+ )}
190
+ </form>
191
+ </div>
192
+ )}
193
+ </div>
194
+
195
+ {/* Social Links */}
196
+ {hasSocialLinks && (
197
+ <div className="mt-10 flex items-center gap-4 border-t border-border pt-8">
198
+ {socialLinks?.twitter && (
199
+ <a
200
+ href={socialLinks.twitter}
201
+ target="_blank"
202
+ rel="noopener noreferrer"
203
+ className="text-muted-foreground transition-colors hover:text-foreground"
204
+ aria-label="X (Twitter)"
205
+ >
206
+ {SocialIcons.twitter}
207
+ </a>
208
+ )}
209
+ {socialLinks?.instagram && (
210
+ <a
211
+ href={socialLinks.instagram}
212
+ target="_blank"
213
+ rel="noopener noreferrer"
214
+ className="text-muted-foreground transition-colors hover:text-foreground"
215
+ aria-label="Instagram"
216
+ >
217
+ {SocialIcons.instagram}
218
+ </a>
219
+ )}
220
+ {socialLinks?.linkedin && (
221
+ <a
222
+ href={socialLinks.linkedin}
223
+ target="_blank"
224
+ rel="noopener noreferrer"
225
+ className="text-muted-foreground transition-colors hover:text-foreground"
226
+ aria-label="LinkedIn"
227
+ >
228
+ {SocialIcons.linkedin}
229
+ </a>
230
+ )}
231
+ {socialLinks?.github && (
232
+ <a
233
+ href={socialLinks.github}
234
+ target="_blank"
235
+ rel="noopener noreferrer"
236
+ className="text-muted-foreground transition-colors hover:text-foreground"
237
+ aria-label="GitHub"
238
+ >
239
+ {SocialIcons.github}
240
+ </a>
241
+ )}
242
+ {socialLinks?.youtube && (
243
+ <a
244
+ href={socialLinks.youtube}
245
+ target="_blank"
246
+ rel="noopener noreferrer"
247
+ className="text-muted-foreground transition-colors hover:text-foreground"
248
+ aria-label="YouTube"
249
+ >
250
+ {SocialIcons.youtube}
251
+ </a>
252
+ )}
253
+ </div>
254
+ )}
255
+ </div>
256
+
257
+ {/* Bottom Bar */}
258
+ <div className="border-t border-border">
259
+ <div className="container mx-auto flex flex-col items-center justify-between gap-4 px-4 py-6 sm:flex-row">
260
+ {/* Logo and Copyright */}
261
+ <div className="flex items-center gap-4">
262
+ <Link href="/" className="flex items-center">
263
+ <Logo variant="auto" className="h-6 w-6" />
264
+ </Link>
265
+ <p className="text-sm text-muted-foreground">
266
+ © {currentYear} {copyrightText || "DirectoryHub"}
267
+ </p>
268
+ </div>
269
+
270
+ {/* Bottom Links and Theme Selector */}
271
+ <div className="flex items-center gap-6">
272
+ {bottomLinks?.map((linkItem) => (
273
+ <Link
274
+ key={linkItem.id || linkItem.link.label}
275
+ href={getLinkUrl(linkItem.link)}
276
+ className="text-sm text-muted-foreground transition-colors hover:text-foreground"
277
+ {...(linkItem.link.newTab ? { target: "_blank", rel: "noopener noreferrer" } : {})}
278
+ >
279
+ {linkItem.link.label}
280
+ </Link>
281
+ ))}
282
+ <ThemeSelector />
283
+ </div>
284
+ </div>
285
+ </div>
286
+ </footer>
287
+ )
288
+ }
@@ -0,0 +1,11 @@
1
+ import { getCachedGlobal } from "@/utilities/getGlobals"
2
+
3
+ import type { Footer as FooterType } from "@/payload-types"
4
+
5
+ import { FooterClient } from "./Component.client"
6
+
7
+ export async function Footer() {
8
+ const footerData: FooterType = await getCachedGlobal("footer", 1)()
9
+
10
+ return <FooterClient data={footerData} />
11
+ }
@@ -0,0 +1,15 @@
1
+ "use client"
2
+ import type { Footer } from "@/payload-types"
3
+ import { type RowLabelProps, useRowLabel } from "@payloadcms/ui"
4
+
5
+ type FooterLink = NonNullable<NonNullable<Footer["columns"]>[number]["links"]>[number]
6
+
7
+ export const RowLabel: React.FC<RowLabelProps> = () => {
8
+ const data = useRowLabel<FooterLink>()
9
+
10
+ const label = data?.data?.link?.label
11
+ ? `Link ${data.rowNumber !== undefined ? data.rowNumber + 1 : ""}: ${data?.data?.link?.label}`
12
+ : "Row"
13
+
14
+ return <div>{label}</div>
15
+ }
@@ -0,0 +1,178 @@
1
+ import type { GlobalConfig } from "payload"
2
+
3
+ import { link } from "@/fields/link"
4
+ import { revalidateFooter } from "./hooks/revalidateFooter"
5
+
6
+ export const Footer: GlobalConfig = {
7
+ slug: "footer",
8
+ access: {
9
+ read: () => true,
10
+ },
11
+ fields: [
12
+ // Link Columns - organized groups of links
13
+ {
14
+ name: "columns",
15
+ type: "array",
16
+ label: "Link Columns",
17
+ maxRows: 5,
18
+ admin: {
19
+ initCollapsed: true,
20
+ description: "Add columns of links (e.g., Solutions, Resources, Company)",
21
+ },
22
+ fields: [
23
+ {
24
+ name: "title",
25
+ type: "text",
26
+ required: true,
27
+ label: "Column Title",
28
+ },
29
+ {
30
+ name: "links",
31
+ type: "array",
32
+ label: "Links",
33
+ maxRows: 10,
34
+ fields: [
35
+ link({
36
+ appearances: false,
37
+ }),
38
+ ],
39
+ admin: {
40
+ initCollapsed: true,
41
+ },
42
+ },
43
+ ],
44
+ },
45
+ // Social Links
46
+ {
47
+ name: "socialLinks",
48
+ type: "group",
49
+ label: "Social Links",
50
+ admin: {
51
+ description: "Add your social media profile URLs",
52
+ },
53
+ fields: [
54
+ {
55
+ name: "twitter",
56
+ type: "text",
57
+ label: "X (Twitter)",
58
+ admin: {
59
+ placeholder: "https://x.com/yourhandle",
60
+ },
61
+ },
62
+ {
63
+ name: "instagram",
64
+ type: "text",
65
+ label: "Instagram",
66
+ admin: {
67
+ placeholder: "https://instagram.com/yourhandle",
68
+ },
69
+ },
70
+ {
71
+ name: "linkedin",
72
+ type: "text",
73
+ label: "LinkedIn",
74
+ admin: {
75
+ placeholder: "https://linkedin.com/company/yourcompany",
76
+ },
77
+ },
78
+ {
79
+ name: "github",
80
+ type: "text",
81
+ label: "GitHub",
82
+ admin: {
83
+ placeholder: "https://github.com/yourorg",
84
+ },
85
+ },
86
+ {
87
+ name: "youtube",
88
+ type: "text",
89
+ label: "YouTube",
90
+ admin: {
91
+ placeholder: "https://youtube.com/@yourchannel",
92
+ },
93
+ },
94
+ ],
95
+ },
96
+ // Newsletter Section
97
+ {
98
+ name: "newsletter",
99
+ type: "group",
100
+ label: "Newsletter",
101
+ admin: {
102
+ description: "Configure the newsletter signup section",
103
+ },
104
+ fields: [
105
+ {
106
+ name: "enabled",
107
+ type: "checkbox",
108
+ label: "Enable Newsletter Signup",
109
+ defaultValue: true,
110
+ },
111
+ {
112
+ name: "title",
113
+ type: "text",
114
+ label: "Title",
115
+ defaultValue: "Newsletter",
116
+ admin: {
117
+ condition: (_, siblingData) => siblingData?.enabled,
118
+ },
119
+ },
120
+ {
121
+ name: "description",
122
+ type: "textarea",
123
+ label: "Description",
124
+ defaultValue: "Stay up to date with the latest updates and news.",
125
+ admin: {
126
+ condition: (_, siblingData) => siblingData?.enabled,
127
+ },
128
+ },
129
+ {
130
+ name: "buttonText",
131
+ type: "text",
132
+ label: "Button Text",
133
+ defaultValue: "Subscribe",
134
+ admin: {
135
+ condition: (_, siblingData) => siblingData?.enabled,
136
+ },
137
+ },
138
+ {
139
+ name: "placeholder",
140
+ type: "text",
141
+ label: "Email Placeholder",
142
+ defaultValue: "Enter your email",
143
+ admin: {
144
+ condition: (_, siblingData) => siblingData?.enabled,
145
+ },
146
+ },
147
+ ],
148
+ },
149
+ // Copyright and Bottom Bar
150
+ {
151
+ name: "copyrightText",
152
+ type: "text",
153
+ label: "Copyright Text",
154
+ defaultValue: "DirectoryHub",
155
+ admin: {
156
+ description: "Company name for copyright (year is added automatically)",
157
+ },
158
+ },
159
+ {
160
+ name: "bottomLinks",
161
+ type: "array",
162
+ label: "Bottom Bar Links",
163
+ maxRows: 4,
164
+ admin: {
165
+ description: "Links shown in the bottom bar (e.g., Contact Support, Privacy Policy)",
166
+ initCollapsed: true,
167
+ },
168
+ fields: [
169
+ link({
170
+ appearances: false,
171
+ }),
172
+ ],
173
+ },
174
+ ],
175
+ hooks: {
176
+ afterChange: [revalidateFooter],
177
+ },
178
+ }
@@ -3,11 +3,11 @@ import type { GlobalAfterChangeHook } from "payload"
3
3
  import { revalidateTag } from "next/cache"
4
4
 
5
5
  export const revalidateFooter: GlobalAfterChangeHook = ({ doc, req: { payload, context } }) => {
6
- if (!context.disableRevalidate) {
7
- payload.logger.info("Revalidating footer")
6
+ if (!context.disableRevalidate) {
7
+ payload.logger.info("Revalidating footer")
8
8
 
9
- revalidateTag("global_footer")
10
- }
9
+ revalidateTag("global_footer")
10
+ }
11
11
 
12
- return doc
12
+ return doc
13
13
  }