bsmnt 0.4.0 → 0.4.2

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 (536) hide show
  1. package/dist/{helpers/add → application/add-hooks}/index.d.ts +4 -4
  2. package/dist/application/add-hooks/index.d.ts.map +1 -0
  3. package/dist/{helpers/add → application/add-hooks}/index.js +22 -35
  4. package/dist/application/add-hooks/index.js.map +1 -0
  5. package/dist/{utils → application/add-integration}/format-results.d.ts +1 -6
  6. package/dist/application/add-integration/format-results.d.ts.map +1 -0
  7. package/dist/{utils → application/add-integration}/format-results.js +1 -6
  8. package/dist/application/add-integration/format-results.js.map +1 -0
  9. package/dist/{helpers/integrate → application/add-integration}/index.d.ts +2 -1
  10. package/dist/application/add-integration/index.d.ts.map +1 -0
  11. package/dist/{helpers/integrate → application/add-integration}/index.js +46 -41
  12. package/dist/application/add-integration/index.js.map +1 -0
  13. package/dist/application/create-project/build-context.d.ts +9 -0
  14. package/dist/application/create-project/build-context.d.ts.map +1 -0
  15. package/dist/application/create-project/build-context.js +13 -0
  16. package/dist/application/create-project/build-context.js.map +1 -0
  17. package/dist/application/create-project/index.d.ts +44 -0
  18. package/dist/application/create-project/index.d.ts.map +1 -0
  19. package/dist/application/create-project/index.js +70 -0
  20. package/dist/application/create-project/index.js.map +1 -0
  21. package/dist/application/create-project/map-selection-to-registry.d.ts +3 -0
  22. package/dist/application/create-project/map-selection-to-registry.d.ts.map +1 -0
  23. package/dist/application/create-project/map-selection-to-registry.js +30 -0
  24. package/dist/application/create-project/map-selection-to-registry.js.map +1 -0
  25. package/dist/application/create-project/resolve-selection.d.ts +15 -0
  26. package/dist/application/create-project/resolve-selection.d.ts.map +1 -0
  27. package/dist/application/create-project/resolve-selection.js +11 -0
  28. package/dist/application/create-project/resolve-selection.js.map +1 -0
  29. package/dist/{helpers/skills → application/install-skills}/index.d.ts +1 -1
  30. package/dist/application/install-skills/index.d.ts.map +1 -0
  31. package/dist/{helpers/skills → application/install-skills}/index.js +31 -44
  32. package/dist/application/install-skills/index.js.map +1 -0
  33. package/dist/{utils/detect-project.d.ts → application/shared/project-detection.d.ts} +8 -15
  34. package/dist/application/shared/project-detection.d.ts.map +1 -0
  35. package/dist/{utils/detect-project.js → application/shared/project-detection.js} +8 -24
  36. package/dist/application/shared/project-detection.js.map +1 -0
  37. package/dist/core/create/build-plan.d.ts +8 -0
  38. package/dist/core/create/build-plan.d.ts.map +1 -0
  39. package/dist/core/create/build-plan.js +89 -0
  40. package/dist/core/create/build-plan.js.map +1 -0
  41. package/dist/core/create/execute-plan.d.ts +23 -0
  42. package/dist/core/create/execute-plan.d.ts.map +1 -0
  43. package/dist/core/create/execute-plan.js +23 -0
  44. package/dist/core/create/execute-plan.js.map +1 -0
  45. package/dist/core/create/internal-ids.d.ts +23 -0
  46. package/dist/core/create/internal-ids.d.ts.map +1 -0
  47. package/dist/core/create/internal-ids.js +36 -0
  48. package/dist/core/create/internal-ids.js.map +1 -0
  49. package/dist/core/create/registry.d.ts +12 -0
  50. package/dist/core/create/registry.d.ts.map +1 -0
  51. package/dist/core/create/registry.js +33 -0
  52. package/dist/core/create/registry.js.map +1 -0
  53. package/dist/core/create/types.d.ts +96 -0
  54. package/dist/core/create/types.d.ts.map +1 -0
  55. package/dist/core/create/types.js +2 -0
  56. package/dist/core/create/types.js.map +1 -0
  57. package/dist/domain/agents.d.ts +61 -0
  58. package/dist/domain/agents.d.ts.map +1 -0
  59. package/dist/domain/agents.js +35 -0
  60. package/dist/domain/agents.js.map +1 -0
  61. package/dist/domain/animations.d.ts +20 -0
  62. package/dist/domain/animations.d.ts.map +1 -0
  63. package/dist/domain/animations.js +13 -0
  64. package/dist/domain/animations.js.map +1 -0
  65. package/dist/domain/cms.d.ts +24 -0
  66. package/dist/domain/cms.d.ts.map +1 -0
  67. package/dist/domain/cms.js +13 -0
  68. package/dist/domain/cms.js.map +1 -0
  69. package/dist/domain/hooks.d.ts +67 -0
  70. package/dist/domain/hooks.d.ts.map +1 -0
  71. package/dist/domain/hooks.js +52 -0
  72. package/dist/domain/hooks.js.map +1 -0
  73. package/dist/domain/skills.d.ts +70 -0
  74. package/dist/domain/skills.d.ts.map +1 -0
  75. package/dist/domain/skills.js +84 -0
  76. package/dist/domain/skills.js.map +1 -0
  77. package/dist/domain/templates.d.ts +51 -0
  78. package/dist/domain/templates.d.ts.map +1 -0
  79. package/dist/domain/templates.js +27 -0
  80. package/dist/domain/templates.js.map +1 -0
  81. package/dist/index.js +124 -115
  82. package/dist/index.js.map +1 -1
  83. package/dist/infrastructure/agents/register-sanity-mcp.d.ts +12 -0
  84. package/dist/infrastructure/agents/register-sanity-mcp.d.ts.map +1 -0
  85. package/dist/infrastructure/agents/register-sanity-mcp.js +153 -0
  86. package/dist/infrastructure/agents/register-sanity-mcp.js.map +1 -0
  87. package/dist/infrastructure/create/apply-copy-paths.d.ts +3 -0
  88. package/dist/infrastructure/create/apply-copy-paths.d.ts.map +1 -0
  89. package/dist/infrastructure/create/apply-copy-paths.js +12 -0
  90. package/dist/infrastructure/create/apply-copy-paths.js.map +1 -0
  91. package/dist/infrastructure/create/apply-merge-paths.d.ts +3 -0
  92. package/dist/infrastructure/create/apply-merge-paths.d.ts.map +1 -0
  93. package/dist/infrastructure/create/apply-merge-paths.js +17 -0
  94. package/dist/infrastructure/create/apply-merge-paths.js.map +1 -0
  95. package/dist/infrastructure/create/apply-package-json.d.ts +8 -0
  96. package/dist/infrastructure/create/apply-package-json.d.ts.map +1 -0
  97. package/dist/infrastructure/create/apply-package-json.js +46 -0
  98. package/dist/infrastructure/create/apply-package-json.js.map +1 -0
  99. package/dist/infrastructure/create/copy-template.d.ts +10 -0
  100. package/dist/infrastructure/create/copy-template.d.ts.map +1 -0
  101. package/dist/infrastructure/create/copy-template.js.map +1 -0
  102. package/dist/infrastructure/create/executor.d.ts +3 -0
  103. package/dist/infrastructure/create/executor.d.ts.map +1 -0
  104. package/dist/infrastructure/create/executor.js +21 -0
  105. package/dist/infrastructure/create/executor.js.map +1 -0
  106. package/dist/{helpers/create/init-git.d.ts → infrastructure/create/init-git-repo.d.ts} +2 -3
  107. package/dist/infrastructure/create/init-git-repo.d.ts.map +1 -0
  108. package/dist/{helpers/create/init-git.js → infrastructure/create/init-git-repo.js} +1 -4
  109. package/dist/infrastructure/create/init-git-repo.js.map +1 -0
  110. package/dist/{helpers/create/install.d.ts → infrastructure/create/install-dependencies.d.ts} +1 -1
  111. package/dist/infrastructure/create/install-dependencies.d.ts.map +1 -0
  112. package/dist/{helpers/create/install.js → infrastructure/create/install-dependencies.js} +1 -1
  113. package/dist/infrastructure/create/install-dependencies.js.map +1 -0
  114. package/dist/infrastructure/create/lifecycle-registry.d.ts +3 -0
  115. package/dist/infrastructure/create/lifecycle-registry.d.ts.map +1 -0
  116. package/dist/infrastructure/create/lifecycle-registry.js +38 -0
  117. package/dist/infrastructure/create/lifecycle-registry.js.map +1 -0
  118. package/dist/infrastructure/create/merge-registry.d.ts +3 -0
  119. package/dist/infrastructure/create/merge-registry.d.ts.map +1 -0
  120. package/dist/infrastructure/create/merge-registry.js +27 -0
  121. package/dist/infrastructure/create/merge-registry.js.map +1 -0
  122. package/dist/infrastructure/create/rename-files.d.ts.map +1 -0
  123. package/dist/infrastructure/create/rename-files.js.map +1 -0
  124. package/dist/{helpers → infrastructure}/create/setup-agent.d.ts +9 -7
  125. package/dist/infrastructure/create/setup-agent.d.ts.map +1 -0
  126. package/dist/infrastructure/create/setup-agent.js +77 -0
  127. package/dist/infrastructure/create/setup-agent.js.map +1 -0
  128. package/dist/infrastructure/create/setup-sanity.d.ts.map +1 -0
  129. package/dist/{helpers → infrastructure}/create/setup-sanity.js +1 -19
  130. package/dist/infrastructure/create/setup-sanity.js.map +1 -0
  131. package/dist/infrastructure/integrations/inject-integration.d.ts +9 -0
  132. package/dist/infrastructure/integrations/inject-integration.d.ts.map +1 -0
  133. package/dist/{helpers/integrate/merge-orchestrator.js → infrastructure/integrations/inject-integration.js} +26 -38
  134. package/dist/infrastructure/integrations/inject-integration.js.map +1 -0
  135. package/dist/modules/features/agents/index.d.ts +3 -0
  136. package/dist/modules/features/agents/index.d.ts.map +1 -0
  137. package/dist/modules/features/agents/index.js +4 -0
  138. package/dist/modules/features/agents/index.js.map +1 -0
  139. package/dist/modules/features/agents/shared.d.ts +4 -0
  140. package/dist/modules/features/agents/shared.d.ts.map +1 -0
  141. package/dist/modules/features/agents/shared.js +21 -0
  142. package/dist/modules/features/agents/shared.js.map +1 -0
  143. package/dist/{configs/animations.d.ts → modules/features/animation/config.d.ts} +1 -1
  144. package/dist/modules/features/animation/config.d.ts.map +1 -0
  145. package/dist/{configs/animations.js → modules/features/animation/config.js} +1 -1
  146. package/dist/modules/features/animation/config.js.map +1 -0
  147. package/dist/modules/features/animation/gsap.d.ts +3 -0
  148. package/dist/modules/features/animation/gsap.d.ts.map +1 -0
  149. package/dist/modules/features/animation/gsap.js +16 -0
  150. package/dist/modules/features/animation/gsap.js.map +1 -0
  151. package/dist/modules/features/animation/index.d.ts +3 -0
  152. package/dist/modules/features/animation/index.d.ts.map +1 -0
  153. package/dist/modules/features/animation/index.js +4 -0
  154. package/dist/modules/features/animation/index.js.map +1 -0
  155. package/dist/modules/features/animation/motion.d.ts +3 -0
  156. package/dist/modules/features/animation/motion.d.ts.map +1 -0
  157. package/dist/modules/features/animation/motion.js +16 -0
  158. package/dist/modules/features/animation/motion.js.map +1 -0
  159. package/dist/modules/features/cms/index.d.ts +3 -0
  160. package/dist/modules/features/cms/index.d.ts.map +1 -0
  161. package/dist/modules/features/cms/index.js +7 -0
  162. package/dist/modules/features/cms/index.js.map +1 -0
  163. package/dist/modules/features/cms/sanity/config.d.ts.map +1 -0
  164. package/dist/{helpers/integrate → modules/features/cms}/sanity/config.js +3 -2
  165. package/dist/modules/features/cms/sanity/config.js.map +1 -0
  166. package/dist/modules/features/cms/sanity/index.d.ts +3 -0
  167. package/dist/modules/features/cms/sanity/index.d.ts.map +1 -0
  168. package/dist/modules/features/cms/sanity/index.js +61 -0
  169. package/dist/modules/features/cms/sanity/index.js.map +1 -0
  170. package/dist/{helpers/integrate/sanity/mergers/check-integration-merger.d.ts → modules/features/cms/sanity/mergers/check-integration.d.ts} +1 -1
  171. package/dist/modules/features/cms/sanity/mergers/check-integration.d.ts.map +1 -0
  172. package/dist/{helpers/integrate/sanity/mergers/check-integration-merger.js → modules/features/cms/sanity/mergers/check-integration.js} +1 -1
  173. package/dist/modules/features/cms/sanity/mergers/check-integration.js.map +1 -0
  174. package/dist/{helpers/integrate/sanity/mergers/layout-merger.d.ts → modules/features/cms/sanity/mergers/layout.d.ts} +1 -1
  175. package/dist/modules/features/cms/sanity/mergers/layout.d.ts.map +1 -0
  176. package/dist/{helpers/integrate/sanity/mergers/layout-merger.js → modules/features/cms/sanity/mergers/layout.js} +1 -1
  177. package/dist/modules/features/cms/sanity/mergers/layout.js.map +1 -0
  178. package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts +13 -0
  179. package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts.map +1 -0
  180. package/dist/modules/features/cms/sanity/mergers/sitemap.js +92 -0
  181. package/dist/modules/features/cms/sanity/mergers/sitemap.js.map +1 -0
  182. package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts +14 -0
  183. package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts.map +1 -0
  184. package/dist/modules/features/cms/sanity-pagebuilder/config.js +44 -0
  185. package/dist/modules/features/cms/sanity-pagebuilder/config.js.map +1 -0
  186. package/dist/modules/features/cms/sanity-pagebuilder/index.d.ts +3 -0
  187. package/dist/modules/features/cms/sanity-pagebuilder/index.d.ts.map +1 -0
  188. package/dist/modules/features/cms/sanity-pagebuilder/index.js +46 -0
  189. package/dist/modules/features/cms/sanity-pagebuilder/index.js.map +1 -0
  190. package/dist/modules/features/hooks/factory.d.ts +4 -0
  191. package/dist/modules/features/hooks/factory.d.ts.map +1 -0
  192. package/dist/modules/features/hooks/factory.js +26 -0
  193. package/dist/modules/features/hooks/factory.js.map +1 -0
  194. package/dist/modules/features/hooks/index.d.ts +3 -0
  195. package/dist/modules/features/hooks/index.d.ts.map +1 -0
  196. package/dist/modules/features/hooks/index.js +4 -0
  197. package/dist/modules/features/hooks/index.js.map +1 -0
  198. package/dist/modules/presets/index.d.ts +3 -0
  199. package/dist/modules/presets/index.d.ts.map +1 -0
  200. package/dist/modules/presets/index.js +11 -0
  201. package/dist/modules/presets/index.js.map +1 -0
  202. package/dist/modules/presets/next-default.d.ts +3 -0
  203. package/dist/modules/presets/next-default.d.ts.map +1 -0
  204. package/dist/modules/presets/next-default.js +9 -0
  205. package/dist/modules/presets/next-default.js.map +1 -0
  206. package/dist/modules/presets/next-experiments.d.ts +3 -0
  207. package/dist/modules/presets/next-experiments.d.ts.map +1 -0
  208. package/dist/modules/presets/next-experiments.js +9 -0
  209. package/dist/modules/presets/next-experiments.js.map +1 -0
  210. package/dist/modules/presets/next-pagebuilder.d.ts +3 -0
  211. package/dist/modules/presets/next-pagebuilder.d.ts.map +1 -0
  212. package/dist/modules/presets/next-pagebuilder.js +10 -0
  213. package/dist/modules/presets/next-pagebuilder.js.map +1 -0
  214. package/dist/modules/presets/next-webgl.d.ts +3 -0
  215. package/dist/modules/presets/next-webgl.d.ts.map +1 -0
  216. package/dist/modules/presets/next-webgl.js +9 -0
  217. package/dist/modules/presets/next-webgl.js.map +1 -0
  218. package/dist/paths.d.ts +7 -1
  219. package/dist/paths.d.ts.map +1 -1
  220. package/dist/paths.js +8 -2
  221. package/dist/paths.js.map +1 -1
  222. package/index.js +2 -2
  223. package/package.json +11 -4
  224. package/src/modules/features/cms/sanity/files/.knip.json +8 -0
  225. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/blog/[slug]/route.ts +3 -4
  226. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/revalidate/route.ts +1 -4
  227. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/blog/[slug]/page.tsx +8 -9
  228. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/layout.tsx +2 -2
  229. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/sitemap.md/route.ts +18 -29
  230. package/src/modules/features/cms/sanity/files/app/sitemap.xml/route.ts +51 -0
  231. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/env.ts +2 -4
  232. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/queries.ts +0 -42
  233. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/index.ts +1 -1
  234. package/src/modules/features/cms/sanity/files/lib/scripts/copy-sanity-mcp.ts +23 -0
  235. package/src/modules/features/cms/sanity/files/lib/scripts/generate-page.ts +297 -0
  236. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/json-ld.tsx +1 -6
  237. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/metadata.ts +2 -2
  238. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/url.ts +4 -2
  239. package/src/{helpers/integrate → modules/features/cms}/sanity/files/proxy.ts +11 -11
  240. package/src/template-hooks/use-device-perf.ts +27 -17
  241. package/src/templates/next-default/.env.example +3 -3
  242. package/src/templates/next-default/.vscode/extensions.json +1 -5
  243. package/src/templates/next-default/.vscode/settings.json +1 -1
  244. package/src/templates/next-default/.zed/settings.json +47 -0
  245. package/src/templates/next-default/README.md +7 -6
  246. package/src/templates/next-default/_gitignore +1 -3
  247. package/src/templates/next-default/app/layout.tsx +21 -35
  248. package/src/templates/next-default/app/robots.ts +3 -4
  249. package/src/templates/next-default/app/sitemap.xml/route.ts +29 -29
  250. package/src/templates/next-default/biome.json +9 -2
  251. package/src/templates/next-default/components/ui/image/index.tsx +2 -1
  252. package/src/templates/next-default/components/ui/link/index.tsx +35 -35
  253. package/src/templates/next-default/lefthook.yml +25 -0
  254. package/src/templates/next-default/lib/README.md +8 -4
  255. package/src/templates/next-default/lib/hooks/use-media.ts +6 -3
  256. package/src/templates/next-default/lib/scripts/dev.ts +32 -0
  257. package/src/templates/next-default/lib/styles/README.md +13 -0
  258. package/src/templates/next-default/lib/styles/fonts.ts +20 -0
  259. package/src/templates/next-default/lib/styles/global.css +15 -196
  260. package/src/templates/next-default/lib/styles/index.css +3 -0
  261. package/src/templates/next-default/lib/styles/tokens.css +182 -0
  262. package/src/templates/next-default/lib/utils/README.md +40 -0
  263. package/src/templates/next-default/lib/utils/easings.ts +240 -0
  264. package/src/templates/next-default/lib/utils/fetch.ts +84 -0
  265. package/src/templates/next-default/lib/utils/global-css.d.ts +1 -0
  266. package/src/templates/next-default/lib/utils/json-ld.tsx +70 -68
  267. package/src/templates/next-default/lib/utils/math.ts +236 -0
  268. package/src/templates/next-default/lib/utils/metadata.ts +26 -27
  269. package/src/templates/next-default/lib/utils/strings.ts +246 -0
  270. package/src/templates/next-default/lib/utils/types.d.ts +15 -0
  271. package/src/templates/next-default/lib/utils/url.ts +8 -5
  272. package/src/templates/next-default/lib/utils/viewport.ts +199 -0
  273. package/src/templates/next-default/package.json +12 -7
  274. package/src/templates/next-default/svg.d.ts +1 -0
  275. package/src/templates/next-experiments/.env.example +3 -3
  276. package/src/templates/next-experiments/.knip.json +3 -0
  277. package/src/templates/next-experiments/.vscode/extensions.json +1 -5
  278. package/src/templates/next-experiments/.vscode/settings.json +1 -1
  279. package/src/templates/next-experiments/.zed/settings.json +47 -0
  280. package/src/templates/next-experiments/README.md +7 -6
  281. package/src/templates/next-experiments/_gitignore +1 -3
  282. package/src/templates/next-experiments/app/layout.tsx +21 -35
  283. package/src/templates/next-experiments/app/robots.ts +5 -2
  284. package/src/templates/next-experiments/app/sitemap.xml/route.ts +51 -0
  285. package/src/templates/next-experiments/biome.json +4 -2
  286. package/src/templates/next-experiments/components/layout/navigation-menu.tsx +1 -1
  287. package/src/templates/next-experiments/components/layout/wrapper/index.tsx +6 -6
  288. package/src/templates/next-experiments/components/ui/image/index.tsx +33 -33
  289. package/src/templates/next-experiments/lib/README.md +8 -4
  290. package/src/templates/next-experiments/lib/hooks/use-media.ts +6 -3
  291. package/src/templates/next-experiments/lib/scripts/dev.ts +32 -0
  292. package/src/templates/next-experiments/lib/styles/README.md +13 -0
  293. package/src/templates/next-experiments/lib/styles/fonts.ts +20 -0
  294. package/src/templates/next-experiments/lib/styles/global.css +16 -196
  295. package/src/templates/next-experiments/lib/styles/index.css +3 -0
  296. package/src/templates/next-experiments/lib/styles/tokens.css +182 -0
  297. package/src/templates/next-experiments/lib/utils/README.md +40 -0
  298. package/src/templates/next-experiments/lib/utils/easings.ts +240 -0
  299. package/src/templates/next-experiments/lib/utils/fetch.ts +84 -0
  300. package/src/templates/next-experiments/lib/utils/global-css.d.ts +1 -0
  301. package/src/templates/next-experiments/lib/utils/json-ld.tsx +70 -68
  302. package/src/templates/next-experiments/lib/utils/math.ts +236 -0
  303. package/src/templates/next-experiments/lib/utils/metadata.ts +26 -27
  304. package/src/templates/next-experiments/lib/utils/strings.ts +246 -0
  305. package/src/templates/next-experiments/lib/utils/types.d.ts +15 -0
  306. package/src/templates/next-experiments/lib/utils/url.ts +8 -5
  307. package/src/templates/next-experiments/lib/utils/viewport.ts +199 -0
  308. package/src/templates/next-experiments/package.json +6 -6
  309. package/src/templates/next-experiments/svg.d.ts +1 -0
  310. package/src/templates/next-pagebuilder/.vscode/extensions.json +16 -0
  311. package/src/templates/next-pagebuilder/.vscode/settings.json +105 -0
  312. package/src/templates/next-pagebuilder/.zed/settings.json +47 -0
  313. package/src/templates/next-pagebuilder/_gitignore +1 -3
  314. package/src/templates/next-pagebuilder/app/(content)/[[...slug]]/page.tsx +17 -8
  315. package/src/templates/next-pagebuilder/app/(content)/layout.tsx +18 -7
  316. package/src/templates/next-pagebuilder/app/actions/refresh.ts +5 -0
  317. package/src/templates/next-pagebuilder/app/robots.ts +3 -4
  318. package/src/templates/next-pagebuilder/biome.json +17 -0
  319. package/src/templates/next-pagebuilder/components/layout/footer/index.tsx +17 -22
  320. package/src/templates/next-pagebuilder/components/layout/header/index.tsx +3 -5
  321. package/src/templates/next-pagebuilder/components/layout/json-ld/index.tsx +11 -10
  322. package/src/templates/next-pagebuilder/components/layout/wrapper/index.tsx +14 -4
  323. package/src/templates/next-pagebuilder/components/page-builder/components/article-content/index.tsx +4 -9
  324. package/src/templates/next-pagebuilder/components/page-builder/components/article-content/related-post-item.tsx +4 -4
  325. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-card.tsx +2 -2
  326. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-filters.tsx +93 -0
  327. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-grid.tsx +7 -9
  328. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-pagination-nav.tsx +71 -0
  329. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/index.tsx +219 -0
  330. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/types.ts +7 -4
  331. package/src/templates/next-pagebuilder/components/page-builder/renderer.tsx +17 -5
  332. package/src/templates/next-pagebuilder/components/page-builder/types.ts +9 -7
  333. package/src/templates/next-pagebuilder/components/page-document/index.tsx +19 -4
  334. package/src/templates/next-pagebuilder/lefthook.yml +25 -0
  335. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.types.ts +208 -0
  336. package/src/templates/next-pagebuilder/lib/styles/global.css +0 -1
  337. package/src/templates/next-pagebuilder/next.config.ts +1 -0
  338. package/src/templates/next-pagebuilder/package.json +13 -26
  339. package/src/templates/next-pagebuilder/postcss.config.mjs +27 -1
  340. package/src/templates/next-pagebuilder/svg.d.ts +1 -0
  341. package/src/templates/next-webgl/.env.example +3 -3
  342. package/src/templates/next-webgl/.vscode/extensions.json +1 -5
  343. package/src/templates/next-webgl/.vscode/settings.json +1 -1
  344. package/src/templates/next-webgl/.zed/settings.json +47 -0
  345. package/src/templates/next-webgl/README.md +7 -6
  346. package/src/templates/next-webgl/_gitignore +1 -3
  347. package/src/templates/next-webgl/app/layout.tsx +21 -35
  348. package/src/templates/next-webgl/app/robots.ts +3 -4
  349. package/src/templates/next-webgl/app/sitemap.xml/route.ts +29 -29
  350. package/src/templates/next-webgl/biome.json +9 -2
  351. package/src/templates/next-webgl/components/ui/image/index.tsx +2 -1
  352. package/src/templates/next-webgl/components/webgl/components/scene/index.tsx +0 -2
  353. package/src/templates/next-webgl/lefthook.yml +25 -0
  354. package/src/templates/next-webgl/lib/README.md +8 -4
  355. package/src/templates/next-webgl/lib/hooks/use-media.ts +6 -3
  356. package/src/templates/next-webgl/lib/scripts/dev.ts +32 -0
  357. package/src/templates/next-webgl/lib/styles/README.md +13 -0
  358. package/src/templates/next-webgl/lib/styles/fonts.ts +20 -0
  359. package/src/templates/next-webgl/lib/styles/global.css +16 -196
  360. package/src/templates/next-webgl/lib/styles/index.css +3 -0
  361. package/src/templates/next-webgl/lib/styles/tokens.css +182 -0
  362. package/src/templates/next-webgl/lib/utils/README.md +40 -0
  363. package/src/templates/next-webgl/lib/utils/easings.ts +240 -0
  364. package/src/templates/next-webgl/lib/utils/fetch.ts +84 -0
  365. package/src/templates/next-webgl/lib/utils/global-css.d.ts +1 -0
  366. package/src/templates/next-webgl/lib/utils/json-ld.tsx +70 -68
  367. package/src/templates/next-webgl/lib/utils/math.ts +236 -0
  368. package/src/templates/next-webgl/lib/utils/metadata.ts +26 -27
  369. package/src/templates/next-webgl/lib/utils/strings.ts +246 -0
  370. package/src/templates/next-webgl/lib/utils/types.d.ts +15 -0
  371. package/src/templates/next-webgl/lib/utils/url.ts +8 -5
  372. package/src/templates/next-webgl/lib/utils/viewport.ts +199 -0
  373. package/src/templates/next-webgl/package.json +13 -8
  374. package/src/templates/next-webgl/svg.d.ts +1 -0
  375. package/src/templates/next-webgl/tsconfig.tsbuildinfo +1 -1
  376. package/dist/configs/animations.d.ts.map +0 -1
  377. package/dist/configs/animations.js.map +0 -1
  378. package/dist/configs/skills.d.ts +0 -27
  379. package/dist/configs/skills.d.ts.map +0 -1
  380. package/dist/configs/skills.js +0 -18
  381. package/dist/configs/skills.js.map +0 -1
  382. package/dist/configs/skills.json +0 -26
  383. package/dist/helpers/add/hooks-config.d.ts +0 -22
  384. package/dist/helpers/add/hooks-config.d.ts.map +0 -1
  385. package/dist/helpers/add/hooks-config.js +0 -31
  386. package/dist/helpers/add/hooks-config.js.map +0 -1
  387. package/dist/helpers/add/index.d.ts.map +0 -1
  388. package/dist/helpers/add/index.js.map +0 -1
  389. package/dist/helpers/create/copy-template.d.ts +0 -11
  390. package/dist/helpers/create/copy-template.d.ts.map +0 -1
  391. package/dist/helpers/create/copy-template.js.map +0 -1
  392. package/dist/helpers/create/index.d.ts +0 -24
  393. package/dist/helpers/create/index.d.ts.map +0 -1
  394. package/dist/helpers/create/index.js +0 -99
  395. package/dist/helpers/create/index.js.map +0 -1
  396. package/dist/helpers/create/init-git.d.ts.map +0 -1
  397. package/dist/helpers/create/init-git.js.map +0 -1
  398. package/dist/helpers/create/install.d.ts.map +0 -1
  399. package/dist/helpers/create/install.js.map +0 -1
  400. package/dist/helpers/create/rename-files.d.ts.map +0 -1
  401. package/dist/helpers/create/rename-files.js.map +0 -1
  402. package/dist/helpers/create/setup-agent.d.ts.map +0 -1
  403. package/dist/helpers/create/setup-agent.js +0 -91
  404. package/dist/helpers/create/setup-agent.js.map +0 -1
  405. package/dist/helpers/create/setup-sanity.d.ts.map +0 -1
  406. package/dist/helpers/create/setup-sanity.js.map +0 -1
  407. package/dist/helpers/create/update-package.d.ts +0 -20
  408. package/dist/helpers/create/update-package.d.ts.map +0 -1
  409. package/dist/helpers/create/update-package.js +0 -97
  410. package/dist/helpers/create/update-package.js.map +0 -1
  411. package/dist/helpers/integrate/index.d.ts.map +0 -1
  412. package/dist/helpers/integrate/index.js.map +0 -1
  413. package/dist/helpers/integrate/merge-config.d.ts +0 -21
  414. package/dist/helpers/integrate/merge-config.d.ts.map +0 -1
  415. package/dist/helpers/integrate/merge-config.js +0 -42
  416. package/dist/helpers/integrate/merge-config.js.map +0 -1
  417. package/dist/helpers/integrate/merge-orchestrator.d.ts +0 -10
  418. package/dist/helpers/integrate/merge-orchestrator.d.ts.map +0 -1
  419. package/dist/helpers/integrate/merge-orchestrator.js.map +0 -1
  420. package/dist/helpers/integrate/sanity/config.d.ts.map +0 -1
  421. package/dist/helpers/integrate/sanity/config.js.map +0 -1
  422. package/dist/helpers/integrate/sanity/mergers/check-integration-merger.d.ts.map +0 -1
  423. package/dist/helpers/integrate/sanity/mergers/check-integration-merger.js.map +0 -1
  424. package/dist/helpers/integrate/sanity/mergers/layout-merger.d.ts.map +0 -1
  425. package/dist/helpers/integrate/sanity/mergers/layout-merger.js.map +0 -1
  426. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.d.ts +0 -11
  427. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.d.ts.map +0 -1
  428. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.js +0 -133
  429. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.js.map +0 -1
  430. package/dist/helpers/skills/index.d.ts.map +0 -1
  431. package/dist/helpers/skills/index.js.map +0 -1
  432. package/dist/utils/detect-project.d.ts.map +0 -1
  433. package/dist/utils/detect-project.js.map +0 -1
  434. package/dist/utils/format-results.d.ts.map +0 -1
  435. package/dist/utils/format-results.js.map +0 -1
  436. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/WEBHOOK-SETUP.md +0 -74
  437. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/sitemap.ts +0 -90
  438. package/src/template-hooks/config.js +0 -32
  439. package/src/templates/next-default/css.d.ts +0 -1
  440. package/src/templates/next-default/lib/utils/portable-text-to-markdown.ts +0 -83
  441. package/src/templates/next-default/tsconfig.tsbuildinfo +0 -1
  442. package/src/templates/next-experiments/css.d.ts +0 -1
  443. package/src/templates/next-experiments/lib/utils/portable-text-to-markdown.ts +0 -83
  444. package/src/templates/next-pagebuilder/app/api/[[...slug]]/route.ts +0 -100
  445. package/src/templates/next-pagebuilder/app/api/draft-mode/disable/route.ts +0 -7
  446. package/src/templates/next-pagebuilder/app/api/draft-mode/enable/route.ts +0 -20
  447. package/src/templates/next-pagebuilder/app/api/revalidate/route.ts +0 -121
  448. package/src/templates/next-pagebuilder/app/sitemap.md/route.ts +0 -124
  449. package/src/templates/next-pagebuilder/app/studio/[[...tool]]/page.tsx +0 -8
  450. package/src/templates/next-pagebuilder/components/page-builder/components/post-collection/index.tsx +0 -28
  451. package/src/templates/next-pagebuilder/components/sanity/draft-mode-toggle.tsx +0 -27
  452. package/src/templates/next-pagebuilder/components/sanity/rich-text.tsx +0 -87
  453. package/src/templates/next-pagebuilder/components/sanity/visual-editing.tsx +0 -27
  454. package/src/templates/next-pagebuilder/components/ui/sanity-image/index.tsx +0 -41
  455. package/src/templates/next-pagebuilder/lib/integrations/check-integration.ts +0 -5
  456. package/src/templates/next-pagebuilder/lib/integrations/sanity/client.ts +0 -27
  457. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/disable-draft-mode.tsx +0 -23
  458. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/page-builder-input.tsx +0 -36
  459. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/page-category-input.tsx +0 -50
  460. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/rich-text.tsx +0 -84
  461. package/src/templates/next-pagebuilder/lib/integrations/sanity/confirm-publish-action.ts +0 -40
  462. package/src/templates/next-pagebuilder/lib/integrations/sanity/env.ts +0 -34
  463. package/src/templates/next-pagebuilder/lib/integrations/sanity/fetchers/layout.ts +0 -35
  464. package/src/templates/next-pagebuilder/lib/integrations/sanity/icons.ts +0 -58
  465. package/src/templates/next-pagebuilder/lib/integrations/sanity/live/index.tsx +0 -61
  466. package/src/templates/next-pagebuilder/lib/integrations/sanity/markdown-proxy.config.ts +0 -50
  467. package/src/templates/next-pagebuilder/lib/integrations/sanity/page-builder-config.ts +0 -132
  468. package/src/templates/next-pagebuilder/lib/integrations/sanity/page-category.ts +0 -28
  469. package/src/templates/next-pagebuilder/lib/integrations/sanity/queries.ts +0 -281
  470. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.cli.ts +0 -29
  471. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.config.ts +0 -211
  472. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/index.ts +0 -4
  473. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +0 -89
  474. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/description.ts +0 -29
  475. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/hero.ts +0 -28
  476. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/singleton/content-collection.ts +0 -45
  477. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/content/author.ts +0 -70
  478. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/content/blog-category.ts +0 -55
  479. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/index.ts +0 -96
  480. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/company-data.ts +0 -62
  481. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/footer.ts +0 -79
  482. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/navbar.ts +0 -74
  483. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/link.ts +0 -125
  484. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/logo-field.ts +0 -9
  485. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/metadata.ts +0 -68
  486. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/nav-objects.ts +0 -192
  487. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page-builder.ts +0 -39
  488. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page-folder.ts +0 -124
  489. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page.ts +0 -232
  490. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/richText.ts +0 -63
  491. package/src/templates/next-pagebuilder/lib/integrations/sanity/singletons.ts +0 -44
  492. package/src/templates/next-pagebuilder/lib/integrations/sanity/structure.ts +0 -453
  493. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/image.ts +0 -8
  494. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/link.ts +0 -137
  495. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/page-builder-markdown.ts +0 -81
  496. package/src/templates/next-pagebuilder/lib/scripts/sanity-typegen.ts +0 -45
  497. package/src/templates/next-pagebuilder/lib/utils/json-ld.tsx +0 -213
  498. package/src/templates/next-pagebuilder/lib/utils/metadata.ts +0 -167
  499. package/src/templates/next-pagebuilder/lib/utils/sitemap.ts +0 -37
  500. package/src/templates/next-pagebuilder/proxy.ts +0 -81
  501. package/src/templates/next-webgl/css.d.ts +0 -1
  502. package/src/templates/next-webgl/lib/utils/portable-text-to-markdown.ts +0 -83
  503. package/dist/{helpers → infrastructure}/create/copy-template.js +0 -0
  504. package/dist/{helpers → infrastructure}/create/rename-files.d.ts +0 -0
  505. package/dist/{helpers → infrastructure}/create/rename-files.js +0 -0
  506. package/dist/{helpers → infrastructure}/create/setup-sanity.d.ts +0 -0
  507. package/dist/{helpers/integrate → modules/features/cms}/sanity/config.d.ts +0 -0
  508. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/draft-mode/disable/route.ts +0 -0
  509. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/draft-mode/enable/route.ts +0 -0
  510. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/studio/[[...tool]]/page.tsx +0 -0
  511. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/studio/layout.tsx +0 -0
  512. package/src/{helpers/integrate → modules/features/cms}/sanity/files/components/ui/sanity-image/index.tsx +0 -0
  513. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/README.md +0 -0
  514. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/check-integration.ts +0 -0
  515. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/MARKDOWN-PROXY.md +0 -0
  516. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/README.md +0 -0
  517. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/client.ts +0 -0
  518. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/components/disable-draft-mode.tsx +0 -0
  519. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/components/rich-text.tsx +0 -0
  520. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/confirm-publish-action.ts +0 -0
  521. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/live/index.tsx +1 -1
  522. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/markdown-proxy.config.ts +0 -0
  523. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.cli.ts +0 -0
  524. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.config.ts +1 -1
  525. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.types.ts +0 -0
  526. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schema.json +0 -0
  527. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/article.ts +0 -0
  528. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/example.ts +0 -0
  529. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/link.ts +0 -0
  530. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/metadata.ts +0 -0
  531. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/navigation.ts +0 -0
  532. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/richText.ts +0 -0
  533. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/structure.ts +0 -0
  534. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/utils/image.ts +0 -0
  535. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/utils/link.ts +0 -0
  536. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/portable-text-to-markdown.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  import { stegaClean } from "next-sanity"
2
- import {
3
- getCompanyData,
4
- getNavbar,
2
+ import type {
3
+ CompanyData,
4
+ NavbarData,
5
5
  } from "@/lib/integrations/sanity/fetchers/layout"
6
6
  import {
7
7
  generateOrganizationJsonLd,
@@ -12,17 +12,18 @@ import {
12
12
  const APP_DESCRIPTION =
13
13
  "Basement is the AI-native platform for audit and advisory firms. Automate engagement workflows using AI agents trusted by 50% of top 100 firms."
14
14
 
15
- export const JsonLd = async () => {
16
- const [navbarData, companyData] = await Promise.all([
17
- getNavbar(),
18
- getCompanyData(),
19
- ])
20
-
15
+ export const JsonLd = ({
16
+ navbar,
17
+ companyData,
18
+ }: {
19
+ navbar: NavbarData | null
20
+ companyData: CompanyData | null
21
+ }) => {
21
22
  const sameAs = companyData?.socialLinks
22
23
  ?.map((link) => stegaClean(link.url))
23
24
  .filter((url): url is string => Boolean(url))
24
25
 
25
- const logoUrl = navbarData?.logo?.asset?.url
26
+ const logoUrl = navbar?.logo?.asset?.url
26
27
 
27
28
  return (
28
29
  <>
@@ -1,9 +1,12 @@
1
1
  import Link from "next/link"
2
2
  import { Footer } from "@/components/layout/footer"
3
3
  import { Header } from "@/components/layout/header"
4
+ import type { SiteLayoutData } from "@/lib/integrations/sanity/fetchers/layout"
4
5
  import { cn } from "@/lib/styles/cn"
5
6
 
6
- interface WrapperProps extends React.HTMLAttributes<HTMLDivElement> {}
7
+ interface WrapperProps
8
+ extends React.HTMLAttributes<HTMLDivElement>,
9
+ SiteLayoutData {}
7
10
 
8
11
  const SkipToMainContent = () => (
9
12
  <Link
@@ -14,10 +17,17 @@ const SkipToMainContent = () => (
14
17
  </Link>
15
18
  )
16
19
 
17
- export const Wrapper = ({ children, className, ...props }: WrapperProps) => (
20
+ export const Wrapper = ({
21
+ children,
22
+ className,
23
+ navbar,
24
+ footer,
25
+ companyData,
26
+ ...props
27
+ }: WrapperProps) => (
18
28
  <>
19
29
  <SkipToMainContent />
20
- <Header />
30
+ <Header data={navbar} />
21
31
  <main
22
32
  id="main-content"
23
33
  className={cn("relative flex grow flex-col", className)}
@@ -25,6 +35,6 @@ export const Wrapper = ({ children, className, ...props }: WrapperProps) => (
25
35
  >
26
36
  {children}
27
37
  </main>
28
- <Footer />
38
+ <Footer footer={footer} companyData={companyData} />
29
39
  </>
30
40
  )
@@ -1,13 +1,10 @@
1
+ import type { ArticleContentProps } from "@/components/page-builder/types"
1
2
  import { RichText } from "@/components/sanity/rich-text"
2
3
  import { SanityImage } from "@/components/ui/sanity-image"
3
4
  import { formatDate } from "@/lib/utils/format-date"
4
- import {RelatedPostItem} from "./related-post-item"
5
- import type { ArticleContentProps } from "@/components/page-builder/types"
6
-
5
+ import { RelatedPostItem } from "./related-post-item"
7
6
 
8
- export function ArticleContent({
9
- block
10
- }: ArticleContentProps) {
7
+ export function ArticleContent({ block }: ArticleContentProps) {
11
8
  const { author, body, categories, date, relatedPosts, thumbnail } = block
12
9
  return (
13
10
  <div className="py-8 md:py-12">
@@ -71,9 +68,7 @@ block
71
68
  {relatedPosts.map((post) => {
72
69
  if (!post.resolvedSlug) return null
73
70
 
74
- return (
75
- <RelatedPostItem key={post._id} post={post} />
76
- )
71
+ return <RelatedPostItem key={post._id} post={post} />
77
72
  })}
78
73
  </ul>
79
74
  </aside>
@@ -1,8 +1,8 @@
1
+ import type { ArticleRelatedPost } from "@/components/page-builder/types"
1
2
  import { Link } from "@/components/ui/link"
2
3
  import { SanityImage } from "@/components/ui/sanity-image"
3
- import type { ArticleRelatedPost } from "@/components/page-builder/types"
4
-
5
- export const RelatedPostItem = ({ post }: {post: ArticleRelatedPost}) => {
4
+
5
+ export const RelatedPostItem = ({ post }: { post: ArticleRelatedPost }) => {
6
6
  return (
7
7
  <li key={post._id}>
8
8
  <Link
@@ -24,4 +24,4 @@ export const RelatedPostItem = ({ post }: {post: ArticleRelatedPost}) => {
24
24
  </Link>
25
25
  </li>
26
26
  )
27
- }
27
+ }
@@ -1,10 +1,10 @@
1
1
  import { Link } from "@/components/ui/link"
2
2
  import { SanityImage } from "@/components/ui/sanity-image"
3
3
  import { formatDate } from "@/lib/utils/format-date"
4
- import type { BlogArticleCard } from "./types"
4
+ import type { ContentItemCard } from "./types"
5
5
 
6
6
  type ContentCardProps = {
7
- article: BlogArticleCard
7
+ article: ContentItemCard
8
8
  className?: string | undefined
9
9
  }
10
10
 
@@ -0,0 +1,93 @@
1
+ "use client"
2
+
3
+ import { usePathname, useRouter, useSearchParams } from "next/navigation"
4
+ import { cn } from "@/lib/styles/cn"
5
+ import type { ContentCategory } from "./types"
6
+
7
+ type ContentFiltersProps = {
8
+ categories: ContentCategory[]
9
+ activeCategory: string
10
+ totalCount: number
11
+ filteredCount: number
12
+ }
13
+
14
+ function FilterChip({
15
+ active,
16
+ label,
17
+ onClick,
18
+ }: {
19
+ active: boolean
20
+ label: string
21
+ onClick: () => void
22
+ }) {
23
+ return (
24
+ <button
25
+ type="button"
26
+ onClick={onClick}
27
+ className={cn(
28
+ "rounded-full border px-4 py-2 text-sm transition-colors",
29
+ active
30
+ ? "border-black bg-black text-white"
31
+ : "border-black/10 bg-white hover:border-black/30"
32
+ )}
33
+ >
34
+ {label}
35
+ </button>
36
+ )
37
+ }
38
+
39
+ export function ContentFilters({
40
+ categories,
41
+ activeCategory,
42
+ totalCount,
43
+ filteredCount,
44
+ }: ContentFiltersProps) {
45
+ const pathname = usePathname()
46
+ const router = useRouter()
47
+ const searchParams = useSearchParams()
48
+
49
+ const navigate = (category: string) => {
50
+ const nextParams = new URLSearchParams(searchParams.toString())
51
+
52
+ if (category) nextParams.set("category", category)
53
+ else nextParams.delete("category")
54
+
55
+ nextParams.delete("page")
56
+
57
+ const href = nextParams.toString()
58
+ ? `${pathname}?${nextParams.toString()}`
59
+ : pathname
60
+
61
+ // biome-ignore lint/suspicious/noExplicitAny: typed routes do not accept dynamic query string helpers cleanly
62
+ router.push(href as any, { scroll: false })
63
+ }
64
+
65
+ return (
66
+ <div className="flex flex-col gap-4 rounded-[1.5rem] border border-black/10 bg-black/[0.02] p-4 sm:p-5">
67
+ <div className="flex flex-wrap gap-2">
68
+ <FilterChip
69
+ active={activeCategory === ""}
70
+ label="All content"
71
+ onClick={() => navigate("")}
72
+ />
73
+ {categories.map((category) => {
74
+ const slug = category.slug?.current
75
+ if (!slug) return null
76
+
77
+ return (
78
+ <FilterChip
79
+ key={category._id}
80
+ active={activeCategory === slug}
81
+ label={category.title || "Untitled"}
82
+ onClick={() => navigate(slug)}
83
+ />
84
+ )
85
+ })}
86
+ </div>
87
+ <p className="text-current/60 text-sm">
88
+ Showing {filteredCount} {filteredCount === 1 ? "item" : "items"}
89
+ {filteredCount !== totalCount ? ` out of ${totalCount}` : ""}
90
+ </p>
91
+ </div>
92
+ )
93
+ }
@@ -1,20 +1,20 @@
1
- import type { BlogArticleCard } from "./types"
2
1
  import { ContentCard } from "./content-card"
2
+ import type { ContentItemCard } from "./types"
3
3
 
4
4
  type ContentGridProps = {
5
- articles: BlogArticleCard[]
5
+ items: ContentItemCard[]
6
6
  start?: number
7
7
  end?: number
8
8
  className?: string
9
9
  }
10
10
 
11
11
  export function ContentGrid({
12
- articles,
12
+ items,
13
13
  start = 0,
14
14
  end,
15
15
  className,
16
16
  }: ContentGridProps) {
17
- const slice = articles.slice(start, end)
17
+ const slice = items.slice(start, end)
18
18
 
19
19
  if (slice.length === 0) {
20
20
  if (start === 0) {
@@ -29,13 +29,11 @@ export function ContentGrid({
29
29
  className ?? "grid grid-cols-2 gap-8 md:grid-cols-2 lg:grid-cols-3"
30
30
  }
31
31
  >
32
- {slice.map((article) => {
33
- const slug = article.resolvedSlug
32
+ {slice.map((item) => {
33
+ const slug = item.resolvedSlug
34
34
  if (!slug) return null
35
35
 
36
- return (
37
- <ContentCard key={article._id} article={article} />
38
- )
36
+ return <ContentCard key={item._id} article={item} />
39
37
  })}
40
38
  </ul>
41
39
  )
@@ -0,0 +1,71 @@
1
+ "use client"
2
+
3
+ import { usePathname, useSearchParams } from "next/navigation"
4
+ import { Link } from "@/components/ui/link"
5
+
6
+ type ContentPaginationNavProps = {
7
+ currentPage: number
8
+ totalPages: number
9
+ }
10
+
11
+ function buildPaginationHref({
12
+ pathname,
13
+ page,
14
+ searchParams,
15
+ }: {
16
+ pathname: string
17
+ page: number
18
+ searchParams: ReturnType<typeof useSearchParams>
19
+ }) {
20
+ const nextParams = new URLSearchParams(searchParams.toString())
21
+
22
+ if (page > 1) nextParams.set("page", String(page))
23
+ else nextParams.delete("page")
24
+
25
+ const query = nextParams.toString()
26
+ return query ? `${pathname}?${query}` : pathname
27
+ }
28
+
29
+ export function ContentPaginationNav({
30
+ currentPage,
31
+ totalPages,
32
+ }: ContentPaginationNavProps) {
33
+ const pathname = usePathname()
34
+ const searchParams = useSearchParams()
35
+
36
+ if (!pathname || totalPages <= 1) return null
37
+
38
+ return (
39
+ <nav className="flex flex-wrap items-center gap-2" aria-label="Pagination">
40
+ {currentPage > 1 ? (
41
+ <Link
42
+ href={buildPaginationHref({
43
+ pathname,
44
+ page: currentPage - 1,
45
+ searchParams,
46
+ })}
47
+ className="rounded-full border border-black/10 px-4 py-2 text-sm transition-colors hover:border-black/30"
48
+ >
49
+ Previous
50
+ </Link>
51
+ ) : null}
52
+
53
+ <span className="text-current/60 text-sm">
54
+ Page {currentPage} of {totalPages}
55
+ </span>
56
+
57
+ {currentPage < totalPages ? (
58
+ <Link
59
+ href={buildPaginationHref({
60
+ pathname,
61
+ page: currentPage + 1,
62
+ searchParams,
63
+ })}
64
+ className="rounded-full border border-black/10 px-4 py-2 text-sm transition-colors hover:border-black/30"
65
+ >
66
+ Next
67
+ </Link>
68
+ ) : null}
69
+ </nav>
70
+ )
71
+ }
@@ -0,0 +1,219 @@
1
+ import { fetchSanity } from "@/lib/integrations/sanity/live"
2
+ import {
3
+ ALL_BLOG_CATEGORIES_QUERY,
4
+ BLOG_ARTICLES_COUNT_QUERY,
5
+ BLOG_ARTICLES_PAGINATED_QUERY,
6
+ } from "@/lib/integrations/sanity/queries"
7
+ import { ContentFilters } from "./content-filters"
8
+ import { ContentGrid } from "./content-grid"
9
+ import { ContentPaginationNav } from "./content-pagination-nav"
10
+ import type {
11
+ ContentCategory,
12
+ ContentCollectionBlock,
13
+ ContentCollectionSearchParams,
14
+ ContentItemCard,
15
+ SearchParams,
16
+ } from "./types"
17
+
18
+ type ContentCollectionProps = {
19
+ block: ContentCollectionBlock
20
+ searchParams: ContentCollectionSearchParams
21
+ }
22
+
23
+ const FEATURED_COUNT = 2
24
+ const PAGE_SIZE = 6
25
+
26
+ const normalizePageValue = (value: string | string[] | undefined) => {
27
+ const page = Number(Array.isArray(value) ? value[0] : value)
28
+ return Number.isFinite(page) && page > 0 ? Math.floor(page) : 1
29
+ }
30
+
31
+ const getCollectionParams = (searchParams: SearchParams) => ({
32
+ currentPage: normalizePageValue(searchParams.page),
33
+ activeCategory:
34
+ typeof searchParams.category === "string" ? searchParams.category : "",
35
+ })
36
+
37
+ const getTotalPages = ({
38
+ activeCategory,
39
+ totalCount,
40
+ }: {
41
+ activeCategory: string
42
+ totalCount: number
43
+ }) => {
44
+ const regularTotal =
45
+ activeCategory === ""
46
+ ? Math.max(0, totalCount - FEATURED_COUNT)
47
+ : totalCount
48
+
49
+ return Math.max(1, Math.ceil(regularTotal / PAGE_SIZE))
50
+ }
51
+
52
+ const getCollectionWindow = ({
53
+ activeCategory,
54
+ currentPage,
55
+ }: {
56
+ activeCategory: string
57
+ currentPage: number
58
+ }) => {
59
+ const isFirstPageNoFilter = currentPage === 1 && activeCategory === ""
60
+
61
+ return {
62
+ isFirstPageNoFilter,
63
+ fetchLimit: isFirstPageNoFilter ? PAGE_SIZE + FEATURED_COUNT : PAGE_SIZE,
64
+ fetchOffset: isFirstPageNoFilter
65
+ ? 0
66
+ : (currentPage - 1) * PAGE_SIZE +
67
+ (activeCategory === "" ? FEATURED_COUNT : 0),
68
+ }
69
+ }
70
+
71
+ function CollectionToolbarSection({
72
+ activeCategory,
73
+ categories,
74
+ totalCount,
75
+ }: {
76
+ activeCategory: string
77
+ categories: ContentCategory[]
78
+ totalCount: number
79
+ }) {
80
+ return (
81
+ <ContentFilters
82
+ categories={categories}
83
+ activeCategory={activeCategory}
84
+ totalCount={totalCount}
85
+ filteredCount={totalCount}
86
+ />
87
+ )
88
+ }
89
+
90
+ function CollectionResultsSection({
91
+ activeCategory,
92
+ items,
93
+ isFirstPageNoFilter,
94
+ subtitle,
95
+ }: {
96
+ activeCategory: string
97
+ items: ContentItemCard[]
98
+ isFirstPageNoFilter: boolean
99
+ subtitle: string | null | undefined
100
+ }) {
101
+ const featuredItems = isFirstPageNoFilter
102
+ ? items.slice(0, FEATURED_COUNT)
103
+ : []
104
+ const regularItems = isFirstPageNoFilter ? items.slice(FEATURED_COUNT) : items
105
+ const isEmpty = featuredItems.length === 0 && regularItems.length === 0
106
+
107
+ return (
108
+ <>
109
+ {featuredItems.length > 0 ? (
110
+ <ContentGrid
111
+ items={featuredItems}
112
+ className="grid grid-cols-1 gap-8 md:grid-cols-2"
113
+ />
114
+ ) : null}
115
+ {isFirstPageNoFilter && activeCategory === "" && subtitle ? (
116
+ <h2 className="font-medium text-2xl leading-tight">{subtitle}</h2>
117
+ ) : null}
118
+ {isEmpty ? (
119
+ <div className="rounded-[1.5rem] border border-black/15 border-dashed bg-black/[0.02] px-6 py-12 text-center">
120
+ <p className="font-medium text-lg">No content found</p>
121
+ <p className="mt-2 text-current/60 text-sm">
122
+ Try a different category to explore more content.
123
+ </p>
124
+ </div>
125
+ ) : (
126
+ <ContentGrid items={regularItems} />
127
+ )}
128
+ </>
129
+ )
130
+ }
131
+
132
+ function CollectionPaginationSection({
133
+ currentPage,
134
+ totalPages,
135
+ }: {
136
+ currentPage: number
137
+ totalPages: number
138
+ }) {
139
+ if (totalPages <= 1) return null
140
+
141
+ return (
142
+ <ContentPaginationNav currentPage={currentPage} totalPages={totalPages} />
143
+ )
144
+ }
145
+
146
+ export async function ContentCollection({
147
+ block,
148
+ searchParams,
149
+ }: ContentCollectionProps) {
150
+ const resolvedParams = (await searchParams) ?? {}
151
+ const { currentPage, activeCategory } = getCollectionParams(resolvedParams)
152
+
153
+ const { data: categoriesData } = await fetchSanity<ContentCategory[]>({
154
+ query: ALL_BLOG_CATEGORIES_QUERY,
155
+ tags: ["blog-categories"],
156
+ })
157
+
158
+ const categories = categoriesData ?? []
159
+ const validCategorySlugs = new Set(
160
+ categories
161
+ .map((category) => category.slug?.current)
162
+ .filter((slug): slug is string => Boolean(slug))
163
+ )
164
+
165
+ const canonicalCategory =
166
+ activeCategory && validCategorySlugs.has(activeCategory)
167
+ ? activeCategory
168
+ : ""
169
+
170
+ const { data: totalCountData } = await fetchSanity<number>({
171
+ query: BLOG_ARTICLES_COUNT_QUERY,
172
+ params: { category: canonicalCategory },
173
+ tags: ["blog-articles-count"],
174
+ })
175
+
176
+ const totalCount = totalCountData ?? 0
177
+ const totalPages = getTotalPages({
178
+ activeCategory: canonicalCategory,
179
+ totalCount,
180
+ })
181
+ const canonicalPage = Math.min(currentPage, totalPages)
182
+
183
+ const { isFirstPageNoFilter, fetchLimit, fetchOffset } = getCollectionWindow({
184
+ activeCategory: canonicalCategory,
185
+ currentPage: canonicalPage,
186
+ })
187
+
188
+ const { data: itemsData } = await fetchSanity<ContentItemCard[]>({
189
+ query: BLOG_ARTICLES_PAGINATED_QUERY,
190
+ params: {
191
+ category: canonicalCategory,
192
+ offset: fetchOffset,
193
+ limit: fetchLimit,
194
+ },
195
+ tags: ["blog-articles"],
196
+ })
197
+
198
+ const items = itemsData ?? []
199
+
200
+ return (
201
+ <section className="flex flex-col gap-8 py-8">
202
+ <CollectionToolbarSection
203
+ activeCategory={canonicalCategory}
204
+ categories={categories}
205
+ totalCount={totalCount}
206
+ />
207
+ <CollectionResultsSection
208
+ activeCategory={canonicalCategory}
209
+ items={items}
210
+ isFirstPageNoFilter={isFirstPageNoFilter}
211
+ subtitle={block.subtitle}
212
+ />
213
+ <CollectionPaginationSection
214
+ currentPage={canonicalPage}
215
+ totalPages={totalPages}
216
+ />
217
+ </section>
218
+ )
219
+ }
@@ -1,10 +1,9 @@
1
1
  import type { PageBuilderBlock } from "@/components/page-builder/types"
2
2
  import type { ALL_BLOG_ARTICLES_QUERY_RESULT } from "@/lib/integrations/sanity/sanity.types"
3
3
 
4
- export type BlogCollectionBlock = Extract<
5
- PageBuilderBlock,
6
- { _type: "blogCollection" }
7
- >
4
+ export type SearchParams = Record<string, string | string[] | undefined>
5
+
6
+ export type ContentCollectionSearchParams = Promise<SearchParams> | undefined
8
7
 
9
8
  export type ContentCollectionBlock = Extract<
10
9
  PageBuilderBlock,
@@ -14,3 +13,7 @@ export type ContentCollectionBlock = Extract<
14
13
  >
15
14
 
16
15
  export type BlogArticleCard = ALL_BLOG_ARTICLES_QUERY_RESULT[number]
16
+ export type ContentCategory = NonNullable<
17
+ NonNullable<BlogArticleCard["blogContent"]>["categories"]
18
+ >[number]
19
+ export type ContentItemCard = BlogArticleCard
@@ -1,29 +1,41 @@
1
1
  import { ArticleContent } from "./components/article-content"
2
+ import { ContentCollection } from "./components/content-collection"
3
+ import type { ContentCollectionSearchParams } from "./components/content-collection/types"
2
4
  import { Description } from "./components/description"
3
5
  import { Hero } from "./components/hero"
4
- import { ContentCollection } from "./components/post-collection"
5
6
  import type { PageBuilderBlock, PageBuilderBlocks } from "./types"
6
7
 
7
8
  type RendererProps = {
8
9
  blocks: PageBuilderBlocks
10
+ searchParams: ContentCollectionSearchParams
9
11
  }
10
12
 
11
- export function Renderer({ blocks }: RendererProps) {
13
+ export function Renderer({ blocks, searchParams }: RendererProps) {
12
14
  if (!blocks?.length) return null
13
15
 
14
16
  return (
15
17
  <div className="space-y-16">
16
18
  {blocks.map((block: PageBuilderBlock) => (
17
- <PageBuilderNode key={block._key} block={block} />
19
+ <PageBuilderNode
20
+ key={block._key}
21
+ block={block}
22
+ searchParams={searchParams}
23
+ />
18
24
  ))}
19
25
  </div>
20
26
  )
21
27
  }
22
28
 
23
- function PageBuilderNode({ block }: { block: PageBuilderBlock }) {
29
+ function PageBuilderNode({
30
+ block,
31
+ searchParams,
32
+ }: {
33
+ block: PageBuilderBlock
34
+ searchParams: ContentCollectionSearchParams
35
+ }) {
24
36
  switch (block._type) {
25
37
  case "blogCollection":
26
- return <ContentCollection block={block} />
38
+ return <ContentCollection block={block} searchParams={searchParams} />
27
39
  case "blogContent":
28
40
  return <ArticleContent block={block} />
29
41
  case "hero":
@@ -6,18 +6,20 @@ export type PageBuilderBlock = NonNullable<
6
6
 
7
7
  export type PageBuilderBlocks = NonNullable<PAGE_QUERY_RESULT>["pageBuilder"]
8
8
 
9
- export type BlogContentBlock = Extract<PageBuilderBlock, { _type: "blogContent" }>
9
+ export type BlogContentBlock = Extract<
10
+ PageBuilderBlock,
11
+ { _type: "blogContent" }
12
+ >
10
13
 
11
14
  export type ArticleContentProps = {
12
15
  block: BlogContentBlock
13
-
14
16
  }
15
17
 
16
18
  export type ArticleRelatedPost = {
17
- _id: string;
18
- title: string | null;
19
- resolvedSlug: string | null;
19
+ _id: string
20
+ title: string | null
21
+ resolvedSlug: string | null
20
22
  metadata?: {
21
- image?: unknown;
23
+ image?: unknown
22
24
  } | null
23
- }
25
+ }