@pro-laico/create-atomic-payload 0.1.4

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 (423) hide show
  1. package/bin/cli.js +159 -0
  2. package/package.json +29 -0
  3. package/template/.env.example +35 -0
  4. package/template/.gitattributes +2 -0
  5. package/template/.prettierrc.json +6 -0
  6. package/template/.vscode/extensions.json +3 -0
  7. package/template/.vscode/launch.json +24 -0
  8. package/template/.vscode/settings.json +86 -0
  9. package/template/.yarnrc +1 -0
  10. package/template/LICENSE.md +22 -0
  11. package/template/README.md +128 -0
  12. package/template/eslint.config.mjs +32 -0
  13. package/template/next-env.d.ts +6 -0
  14. package/template/next.config.ts +36 -0
  15. package/template/package.json +75 -0
  16. package/template/public/adminFavicon.svg +1 -0
  17. package/template/public/ogImage.webp +0 -0
  18. package/template/src/access/anyone.ts +3 -0
  19. package/template/src/access/authenticated.ts +7 -0
  20. package/template/src/access/authenticatedOrPublished.ts +6 -0
  21. package/template/src/app/(frontend)/[...slug]/page.tsx +48 -0
  22. package/template/src/app/(frontend)/layout.tsx +49 -0
  23. package/template/src/app/(frontend)/next/exit-preview/route.ts +7 -0
  24. package/template/src/app/(frontend)/next/preview/route.ts +45 -0
  25. package/template/src/app/(frontend)/next/seed/route.ts +31 -0
  26. package/template/src/app/(frontend)/not-found.tsx +93 -0
  27. package/template/src/app/(frontend)/page.tsx +5 -0
  28. package/template/src/app/(frontend)/sitemap.ts +14 -0
  29. package/template/src/app/(payload)/admin/[[...segments]]/not-found.tsx +24 -0
  30. package/template/src/app/(payload)/admin/[[...segments]]/page.tsx +24 -0
  31. package/template/src/app/(payload)/admin/importMap.js +85 -0
  32. package/template/src/app/(payload)/api/[...slug]/route.ts +19 -0
  33. package/template/src/app/(payload)/custom.scss +29 -0
  34. package/template/src/app/(payload)/layout.tsx +31 -0
  35. package/template/src/blocks/actions/blocks.ts +27 -0
  36. package/template/src/blocks/actions/cookieConsent/set/block.ts +17 -0
  37. package/template/src/blocks/actions/cookieConsent/set/filter.ts +3 -0
  38. package/template/src/blocks/actions/cookieConsent/set/options.ts +35 -0
  39. package/template/src/blocks/actions/cookieConsent/toDA/block.ts +14 -0
  40. package/template/src/blocks/actions/cookieConsent/toDA/filter.ts +3 -0
  41. package/template/src/blocks/actions/cookieConsent/toDA/options.ts +19 -0
  42. package/template/src/blocks/actions/dynamicStore/boolean/set/block.ts +15 -0
  43. package/template/src/blocks/actions/dynamicStore/boolean/set/filter.ts +4 -0
  44. package/template/src/blocks/actions/dynamicStore/boolean/set/options.ts +18 -0
  45. package/template/src/blocks/actions/dynamicStore/boolean/toDA/block.ts +10 -0
  46. package/template/src/blocks/actions/dynamicStore/boolean/toDA/filter.ts +3 -0
  47. package/template/src/blocks/actions/dynamicStore/boolean/toDA/options.ts +12 -0
  48. package/template/src/blocks/actions/dynamicStore/text/cycle/block.ts +41 -0
  49. package/template/src/blocks/actions/dynamicStore/text/cycle/filter.ts +4 -0
  50. package/template/src/blocks/actions/dynamicStore/text/cycle/options.ts +23 -0
  51. package/template/src/blocks/actions/dynamicStore/text/toDA/block.ts +10 -0
  52. package/template/src/blocks/actions/dynamicStore/text/toDA/filter.ts +3 -0
  53. package/template/src/blocks/actions/dynamicStore/text/toDA/options.ts +12 -0
  54. package/template/src/blocks/actions/filters.ts +27 -0
  55. package/template/src/blocks/actions/form/errorToDA/block.ts +18 -0
  56. package/template/src/blocks/actions/form/errorToDA/filter.ts +3 -0
  57. package/template/src/blocks/actions/form/errorToDA/options.ts +15 -0
  58. package/template/src/blocks/actions/form/reset/block.ts +18 -0
  59. package/template/src/blocks/actions/form/reset/filter.ts +3 -0
  60. package/template/src/blocks/actions/form/reset/options.ts +30 -0
  61. package/template/src/blocks/actions/form/statusToDA/block.ts +12 -0
  62. package/template/src/blocks/actions/form/statusToDA/filter.ts +3 -0
  63. package/template/src/blocks/actions/form/statusToDA/options.ts +15 -0
  64. package/template/src/blocks/actions/form/submit/block.ts +18 -0
  65. package/template/src/blocks/actions/form/submit/filter.ts +3 -0
  66. package/template/src/blocks/actions/form/submit/options.ts +35 -0
  67. package/template/src/blocks/actions/portal/set/block.ts +25 -0
  68. package/template/src/blocks/actions/portal/set/filter.ts +3 -0
  69. package/template/src/blocks/actions/portal/set/options.ts +43 -0
  70. package/template/src/blocks/actions/processor.ts +263 -0
  71. package/template/src/blocks/actions/theme/set/block.ts +10 -0
  72. package/template/src/blocks/actions/theme/set/filter.ts +3 -0
  73. package/template/src/blocks/actions/theme/set/options.ts +9 -0
  74. package/template/src/blocks/actions/zap.ts +4 -0
  75. package/template/src/blocks/children/atomic/block.ts +123 -0
  76. package/template/src/blocks/children/atomic/controlBar.ts +43 -0
  77. package/template/src/blocks/children/atomic/variants/button/typeField.ts +16 -0
  78. package/template/src/blocks/children/atomic/variants/button/variants/link/component.client.tsx +21 -0
  79. package/template/src/blocks/children/atomic/variants/button/variants/link/component.tsx +13 -0
  80. package/template/src/blocks/children/atomic/variants/button/variants/link/controlBar.ts +73 -0
  81. package/template/src/blocks/children/atomic/variants/button/variants/link/settings.ts +26 -0
  82. package/template/src/blocks/children/atomic/variants/button/variants/portal/controlBar.ts +35 -0
  83. package/template/src/blocks/children/atomic/variants/button/variants/portal/dialog/component.tsx +36 -0
  84. package/template/src/blocks/children/atomic/variants/button/variants/portal/dialog/settings.ts +24 -0
  85. package/template/src/blocks/children/atomic/variants/button/variants/portal/popover/component.tsx +41 -0
  86. package/template/src/blocks/children/atomic/variants/button/variants/portal/popover/settings.ts +111 -0
  87. package/template/src/blocks/children/atomic/variants/button/variants/regular/component.client.tsx +19 -0
  88. package/template/src/blocks/children/atomic/variants/button/variants/regular/component.tsx +11 -0
  89. package/template/src/blocks/children/atomic/variants/form/component.tsx +18 -0
  90. package/template/src/blocks/children/atomic/variants/form/controlBar.ts +22 -0
  91. package/template/src/blocks/children/atomic/variants/form/settings.ts +20 -0
  92. package/template/src/blocks/children/atomic/variants/input/autoCompleteOptions.ts +51 -0
  93. package/template/src/blocks/children/atomic/variants/input/controlBar.ts +13 -0
  94. package/template/src/blocks/children/atomic/variants/input/settings.ts +35 -0
  95. package/template/src/blocks/children/atomic/variants/input/typeField.ts +23 -0
  96. package/template/src/blocks/children/atomic/variants/input/variants/checkBox/component.client.tsx +12 -0
  97. package/template/src/blocks/children/atomic/variants/input/variants/checkBox/component.tsx +6 -0
  98. package/template/src/blocks/children/atomic/variants/input/variants/checkBox/settings.ts +9 -0
  99. package/template/src/blocks/children/atomic/variants/input/variants/number/component.client.tsx +12 -0
  100. package/template/src/blocks/children/atomic/variants/input/variants/number/component.tsx +6 -0
  101. package/template/src/blocks/children/atomic/variants/input/variants/number/settings.ts +9 -0
  102. package/template/src/blocks/children/atomic/variants/input/variants/radio/component.client.tsx +12 -0
  103. package/template/src/blocks/children/atomic/variants/input/variants/radio/component.tsx +6 -0
  104. package/template/src/blocks/children/atomic/variants/input/variants/radio/settings.ts +9 -0
  105. package/template/src/blocks/children/atomic/variants/input/variants/text/component.client.tsx +12 -0
  106. package/template/src/blocks/children/atomic/variants/input/variants/text/component.tsx +7 -0
  107. package/template/src/blocks/children/atomic/variants/input/variants/text/settings.ts +12 -0
  108. package/template/src/blocks/children/atomic/variants/tag/component.client.tsx +17 -0
  109. package/template/src/blocks/children/atomic/variants/tag/component.tsx +13 -0
  110. package/template/src/blocks/children/atomic/variants/tag/controlBar.ts +6 -0
  111. package/template/src/blocks/children/atomic/variants/tag/settings.ts +9 -0
  112. package/template/src/blocks/children/blocks.ts +13 -0
  113. package/template/src/blocks/children/icon/block.ts +41 -0
  114. package/template/src/blocks/children/icon/component.tsx +17 -0
  115. package/template/src/blocks/children/image/block.ts +80 -0
  116. package/template/src/blocks/children/image/component.tsx +21 -0
  117. package/template/src/blocks/children/richText/block.ts +50 -0
  118. package/template/src/blocks/children/richText/component/converters/index.tsx +10 -0
  119. package/template/src/blocks/children/richText/component/converters/internalLink.tsx +8 -0
  120. package/template/src/blocks/children/richText/component/index.tsx +10 -0
  121. package/template/src/blocks/children/richText/component.tsx +7 -0
  122. package/template/src/blocks/children/richText/defaultLexical.ts +65 -0
  123. package/template/src/blocks/children/simpleText/block.ts +41 -0
  124. package/template/src/blocks/children/simpleText/component.client.tsx +18 -0
  125. package/template/src/blocks/children/simpleText/component.tsx +11 -0
  126. package/template/src/blocks/children/svg/block.ts +39 -0
  127. package/template/src/blocks/children/svg/component.tsx +6 -0
  128. package/template/src/blocks/children/video/block.ts +70 -0
  129. package/template/src/blocks/children/video/component.tsx +11 -0
  130. package/template/src/blocks/children/zap.ts +54 -0
  131. package/template/src/blocks/submitForm/form/rateLimiting/blocks.ts +5 -0
  132. package/template/src/blocks/submitForm/form/rateLimiting/functions.ts +1 -0
  133. package/template/src/blocks/submitForm/form/rateLimiting/simpleSlidingWindow/block.ts +23 -0
  134. package/template/src/blocks/submitForm/form/rateLimiting/simpleSlidingWindow/serverFunction.ts +46 -0
  135. package/template/src/blocks/submitForm/form/sanitation/blocks.ts +6 -0
  136. package/template/src/blocks/submitForm/form/sanitation/combineTwoFields/block.ts +19 -0
  137. package/template/src/blocks/submitForm/form/sanitation/combineTwoFields/serverFunction.ts +22 -0
  138. package/template/src/blocks/submitForm/form/sanitation/functions.ts +1 -0
  139. package/template/src/blocks/submitForm/form/validation/blocks.ts +6 -0
  140. package/template/src/blocks/submitForm/form/validation/functions.ts +1 -0
  141. package/template/src/blocks/submitForm/form/validation/isUnique/block.ts +19 -0
  142. package/template/src/blocks/submitForm/form/validation/isUnique/serverFunction.ts +40 -0
  143. package/template/src/blocks/submitForm/form/zap.ts +8 -0
  144. package/template/src/blocks/submitForm/formProcessor.ts +222 -0
  145. package/template/src/blocks/submitForm/input/sanitation/blocks.ts +5 -0
  146. package/template/src/blocks/submitForm/input/sanitation/functions.ts +1 -0
  147. package/template/src/blocks/submitForm/input/sanitation/trimText/block.ts +24 -0
  148. package/template/src/blocks/submitForm/input/sanitation/trimText/serverFunction.ts +63 -0
  149. package/template/src/blocks/submitForm/input/useOn.ts +8 -0
  150. package/template/src/blocks/submitForm/input/validation/blocks.ts +6 -0
  151. package/template/src/blocks/submitForm/input/validation/contains/block.ts +12 -0
  152. package/template/src/blocks/submitForm/input/validation/contains/serverFunction.ts +23 -0
  153. package/template/src/blocks/submitForm/input/validation/doesNotContain/block.ts +12 -0
  154. package/template/src/blocks/submitForm/input/validation/doesNotContain/serverFunction.ts +23 -0
  155. package/template/src/blocks/submitForm/input/validation/functions.ts +2 -0
  156. package/template/src/blocks/submitForm/input/zap.ts +6 -0
  157. package/template/src/blocks/submitForm/serverFunction.ts +42 -0
  158. package/template/src/collections/designSets/collection.ts +44 -0
  159. package/template/src/collections/designSets/defaults.ts +20 -0
  160. package/template/src/collections/designSets/tabs/animation.ts +71 -0
  161. package/template/src/collections/designSets/tabs/colors.ts +31 -0
  162. package/template/src/collections/designSets/tabs/fonts.ts +53 -0
  163. package/template/src/collections/designSets/tabs/miscellaneous.ts +22 -0
  164. package/template/src/collections/designSets/tabs/prose.ts +151 -0
  165. package/template/src/collections/designSets/tabs/settings.ts +52 -0
  166. package/template/src/collections/designSets/tabs/sizes.ts +30 -0
  167. package/template/src/collections/designSets/tabs/storage.ts +51 -0
  168. package/template/src/collections/designSets/tabs/variables.ts +28 -0
  169. package/template/src/collections/favicons.ts +11 -0
  170. package/template/src/collections/fonts/collection.ts +20 -0
  171. package/template/src/collections/fonts/script.ts +199 -0
  172. package/template/src/collections/footers/collection.ts +48 -0
  173. package/template/src/collections/footers/component.tsx +13 -0
  174. package/template/src/collections/headers/collection.ts +47 -0
  175. package/template/src/collections/headers/component.tsx +13 -0
  176. package/template/src/collections/iconSets/collection.ts +80 -0
  177. package/template/src/collections/iconSets/defaults.ts +81 -0
  178. package/template/src/collections/icons.ts +20 -0
  179. package/template/src/collections/images.ts +29 -0
  180. package/template/src/collections/index.ts +17 -0
  181. package/template/src/collections/muxVideos.ts +13 -0
  182. package/template/src/collections/pages/collection.ts +88 -0
  183. package/template/src/collections/pages/tabs/SEO.ts +70 -0
  184. package/template/src/collections/pages/tabs/settings.ts +17 -0
  185. package/template/src/collections/posthogProperty.ts +48 -0
  186. package/template/src/collections/shortcutSets/collection.ts +30 -0
  187. package/template/src/collections/shortcutSets/defaults.ts +1 -0
  188. package/template/src/collections/shortcutSets/protectedNames.ts +135 -0
  189. package/template/src/collections/shortcutSets/tabs/settings.ts +13 -0
  190. package/template/src/collections/shortcutSets/tabs/shortcuts.ts +70 -0
  191. package/template/src/collections/users.ts +11 -0
  192. package/template/src/collections/zap.ts +59 -0
  193. package/template/src/components/child/SSRProps.ts +381 -0
  194. package/template/src/components/child/renderChildren.tsx +148 -0
  195. package/template/src/components/livePreviewListener.tsx +10 -0
  196. package/template/src/components/providers/formProvider.tsx +11 -0
  197. package/template/src/components/providers/tracking/gtm.tsx +11 -0
  198. package/template/src/components/providers/tracking/index.tsx +46 -0
  199. package/template/src/components/providers/tracking/postHog.tsx +41 -0
  200. package/template/src/components/providers/tracking/vercel.tsx +10 -0
  201. package/template/src/components/toast/index.module.css +142 -0
  202. package/template/src/components/toast/index.tsx +55 -0
  203. package/template/src/endpoints/seed/backendForm.ts +48 -0
  204. package/template/src/endpoints/seed/designSet.ts +476 -0
  205. package/template/src/endpoints/seed/footer.ts +389 -0
  206. package/template/src/endpoints/seed/header.ts +3511 -0
  207. package/template/src/endpoints/seed/iconSet.ts +19 -0
  208. package/template/src/endpoints/seed/icons/assets/check.svg +4 -0
  209. package/template/src/endpoints/seed/icons/assets/close.svg +4 -0
  210. package/template/src/endpoints/seed/icons/assets/cookie.svg +7 -0
  211. package/template/src/endpoints/seed/icons/assets/github.svg +1 -0
  212. package/template/src/endpoints/seed/icons/assets/logo.svg +11 -0
  213. package/template/src/endpoints/seed/icons/assets/menu.svg +4 -0
  214. package/template/src/endpoints/seed/icons/assets/theme.svg +4 -0
  215. package/template/src/endpoints/seed/icons/check.ts +14 -0
  216. package/template/src/endpoints/seed/icons/close.ts +14 -0
  217. package/template/src/endpoints/seed/icons/cookie.ts +14 -0
  218. package/template/src/endpoints/seed/icons/github.ts +14 -0
  219. package/template/src/endpoints/seed/icons/index.ts +7 -0
  220. package/template/src/endpoints/seed/icons/logo.ts +14 -0
  221. package/template/src/endpoints/seed/icons/menu.ts +14 -0
  222. package/template/src/endpoints/seed/icons/theme.ts +14 -0
  223. package/template/src/endpoints/seed/index.ts +100 -0
  224. package/template/src/endpoints/seed/pages/home.ts +858 -0
  225. package/template/src/endpoints/seed/pages/index.ts +4 -0
  226. package/template/src/endpoints/seed/pages/notFoundPage.ts +287 -0
  227. package/template/src/endpoints/seed/pages/prose.ts +1436 -0
  228. package/template/src/endpoints/seed/pages/testing.ts +2181 -0
  229. package/template/src/endpoints/seed/shortcutSet.ts +187 -0
  230. package/template/src/endpoints/seed/siteMetaData.ts +10 -0
  231. package/template/src/fields/actions/changeKey.ts +12 -0
  232. package/template/src/fields/actions/index.ts +6 -0
  233. package/template/src/fields/actions/initialValueCheckbox.ts +14 -0
  234. package/template/src/fields/actions/keyText.ts +10 -0
  235. package/template/src/fields/actions/persisted.ts +14 -0
  236. package/template/src/fields/actions/setData.ts +20 -0
  237. package/template/src/fields/actions/strict/index.ts +3 -0
  238. package/template/src/fields/actions/strict/keySelect.ts +28 -0
  239. package/template/src/fields/actions/strict/listenSelect.ts +28 -0
  240. package/template/src/fields/actions/strict/performSelect.ts +30 -0
  241. package/template/src/fields/actions/strict/registry/cookieConsent.ts +14 -0
  242. package/template/src/fields/actions/strict/registry/index.ts +6 -0
  243. package/template/src/fields/actions/strict/registry/theme.ts +9 -0
  244. package/template/src/fields/active.ts +16 -0
  245. package/template/src/fields/apf/index.ts +69 -0
  246. package/template/src/fields/apf/storage.ts +38 -0
  247. package/template/src/fields/blocks/actions.ts +30 -0
  248. package/template/src/fields/blocks/backdropChildren.ts +11 -0
  249. package/template/src/fields/blocks/children.ts +15 -0
  250. package/template/src/fields/blocks/submitForm/form.ts +24 -0
  251. package/template/src/fields/blocks/submitForm/input.ts +25 -0
  252. package/template/src/fields/className.ts +26 -0
  253. package/template/src/fields/coloredEnd.ts +5 -0
  254. package/template/src/fields/defaultOpen.ts +14 -0
  255. package/template/src/fields/designSets/value.ts +80 -0
  256. package/template/src/fields/devMode.ts +11 -0
  257. package/template/src/fields/favicon.ts +18 -0
  258. package/template/src/fields/for.ts +11 -0
  259. package/template/src/fields/keepMounted.ts +11 -0
  260. package/template/src/fields/modal.ts +16 -0
  261. package/template/src/fields/slug.ts +35 -0
  262. package/template/src/fields/staticDataAttributes.ts +29 -0
  263. package/template/src/fields/tabs/block/children/actions.ts +49 -0
  264. package/template/src/fields/tabs/block/children/backdrop.ts +17 -0
  265. package/template/src/fields/tabs/block/children/settings.ts +45 -0
  266. package/template/src/fields/tabs/block/children/submitForm/form.ts +23 -0
  267. package/template/src/fields/tabs/block/children/submitForm/input.ts +14 -0
  268. package/template/src/fields/tabs/block/children/tracking.ts +25 -0
  269. package/template/src/fields/tabs/collection/storage.ts +55 -0
  270. package/template/src/fields/tagType.ts +32 -0
  271. package/template/src/fields/testPath.ts +3 -0
  272. package/template/src/fields/uniqueTitle.ts +8 -0
  273. package/template/src/fields/validationMessage.ts +13 -0
  274. package/template/src/globals/index.ts +8 -0
  275. package/template/src/globals/settings.ts +36 -0
  276. package/template/src/globals/siteMetaData.ts +29 -0
  277. package/template/src/globals/storage.ts +15 -0
  278. package/template/src/globals/tracking/global.ts +25 -0
  279. package/template/src/globals/tracking/tabs/gtm.ts +18 -0
  280. package/template/src/globals/tracking/tabs/postHog.ts +35 -0
  281. package/template/src/hooks/collection/atomicHook/atomicHook.ts +223 -0
  282. package/template/src/hooks/collection/atomicHook/processors/cssProcessor.ts +60 -0
  283. package/template/src/hooks/collection/atomicHook/processors/processDesignSet/generatePreflights.ts +36 -0
  284. package/template/src/hooks/collection/atomicHook/processors/processDesignSet/index.ts +176 -0
  285. package/template/src/hooks/collection/atomicHook/processors/unsetActive.ts +24 -0
  286. package/template/src/hooks/collection/formatSVG.ts +157 -0
  287. package/template/src/hooks/collection/revalidate.ts +53 -0
  288. package/template/src/hooks/collection/sanitizeCollection.ts +5 -0
  289. package/template/src/hooks/field/apf.ts +59 -0
  290. package/template/src/hooks/field/formatSlug.ts +23 -0
  291. package/template/src/hooks/field/href.ts +6 -0
  292. package/template/src/hooks/field/publishedAt.ts +5 -0
  293. package/template/src/hooks/frontEnd/atomicStore/create.ts +69 -0
  294. package/template/src/hooks/frontEnd/atomicStore/index.tsx +20 -0
  295. package/template/src/hooks/frontEnd/atomicStore/slices/base.ts +7 -0
  296. package/template/src/hooks/frontEnd/atomicStore/slices/consent.ts +76 -0
  297. package/template/src/hooks/frontEnd/atomicStore/slices/dynamic.ts +51 -0
  298. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/boolToDA/function.ts +14 -0
  299. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/boolToDA/zap.ts +12 -0
  300. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/cCToDA/function.ts +34 -0
  301. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/cCToDA/zap.ts +17 -0
  302. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/errorToDA/function.ts +22 -0
  303. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/errorToDA/zap.ts +10 -0
  304. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/function.ts +20 -0
  305. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/statusToDA/function.ts +24 -0
  306. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/statusToDA/zap.ts +10 -0
  307. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/textToDA/function.ts +21 -0
  308. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/textToDA/zap.ts +12 -0
  309. package/template/src/hooks/frontEnd/useActions/dispatch/attributer/zap.ts +15 -0
  310. package/template/src/hooks/frontEnd/useActions/dispatch/index.ts +2 -0
  311. package/template/src/hooks/frontEnd/useActions/dispatch/runner/cycleText/function.ts +30 -0
  312. package/template/src/hooks/frontEnd/useActions/dispatch/runner/cycleText/zap.ts +12 -0
  313. package/template/src/hooks/frontEnd/useActions/dispatch/runner/function.ts +21 -0
  314. package/template/src/hooks/frontEnd/useActions/dispatch/runner/resetForm/function.ts +7 -0
  315. package/template/src/hooks/frontEnd/useActions/dispatch/runner/resetForm/zap.ts +9 -0
  316. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setBool/function.ts +10 -0
  317. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setBool/zap.ts +11 -0
  318. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setCCs/function.ts +33 -0
  319. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setCCs/zap.ts +14 -0
  320. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setThemes/function.ts +11 -0
  321. package/template/src/hooks/frontEnd/useActions/dispatch/runner/setThemes/zap.ts +10 -0
  322. package/template/src/hooks/frontEnd/useActions/dispatch/runner/submitForm/function.ts +32 -0
  323. package/template/src/hooks/frontEnd/useActions/dispatch/runner/submitForm/zap.ts +9 -0
  324. package/template/src/hooks/frontEnd/useActions/dispatch/runner/zap.ts +16 -0
  325. package/template/src/hooks/frontEnd/useActions/dispatch/zap.ts +2 -0
  326. package/template/src/hooks/frontEnd/useActions/index.ts +6 -0
  327. package/template/src/hooks/frontEnd/useActions/useActionContext.ts +21 -0
  328. package/template/src/hooks/frontEnd/useActions/useButtonActions.ts +17 -0
  329. package/template/src/hooks/frontEnd/useActions/useDaToText.ts +34 -0
  330. package/template/src/hooks/frontEnd/useActions/useForm.ts +114 -0
  331. package/template/src/hooks/frontEnd/useActions/usePortal.ts +33 -0
  332. package/template/src/hooks/frontEnd/useActions/useToDa.ts +12 -0
  333. package/template/src/hooks/global/revalidate.ts +26 -0
  334. package/template/src/payload.config.ts +78 -0
  335. package/template/src/plugins/blurDataUrls.ts +8 -0
  336. package/template/src/plugins/formBuilder.ts +40 -0
  337. package/template/src/plugins/index.ts +17 -0
  338. package/template/src/plugins/muxVideo.ts +13 -0
  339. package/template/src/plugins/nestedDocs.ts +9 -0
  340. package/template/src/plugins/vercelBlobStorage.ts +8 -0
  341. package/template/src/ts/JSONSchema.ts +93 -0
  342. package/template/src/ts/declarations.ts +24 -0
  343. package/template/src/ts/types/actions.ts +175 -0
  344. package/template/src/ts/types/apf.ts +108 -0
  345. package/template/src/ts/types/cache.ts +166 -0
  346. package/template/src/ts/types/css.ts +14 -0
  347. package/template/src/ts/types/forms.ts +214 -0
  348. package/template/src/ts/types/frontEnd.ts +115 -0
  349. package/template/src/ts/types/index.ts +49 -0
  350. package/template/src/ts/types/payload-types.ts +3684 -0
  351. package/template/src/ts/zap/ap.ts +82 -0
  352. package/template/src/ts/zap/index.ts +4 -0
  353. package/template/src/ui/apf/controls.tsx +88 -0
  354. package/template/src/ui/apf/field.tsx +81 -0
  355. package/template/src/ui/apf/index.scss +59 -0
  356. package/template/src/ui/apf/label.tsx +23 -0
  357. package/template/src/ui/assets/Icon.tsx +21 -0
  358. package/template/src/ui/assets/Logo.tsx +21 -0
  359. package/template/src/ui/assets/atomicIcon.tsx +27 -0
  360. package/template/src/ui/assets/warningIcon.ts +6 -0
  361. package/template/src/ui/blocks/actionBlock.tsx +44 -0
  362. package/template/src/ui/blocks/inputBlock.tsx +24 -0
  363. package/template/src/ui/decorative/coloredEnd.tsx +16 -0
  364. package/template/src/ui/decorative/index.scss +46 -0
  365. package/template/src/ui/fields/iconSelect/index.tsx +19 -0
  366. package/template/src/ui/fields/slug/index.scss +12 -0
  367. package/template/src/ui/fields/slug/index.tsx +72 -0
  368. package/template/src/ui/index.ts +32 -0
  369. package/template/src/ui/root/beforeDashboard/index.scss +22 -0
  370. package/template/src/ui/root/beforeDashboard/index.tsx +39 -0
  371. package/template/src/ui/root/beforeDashboard/seedButton/index.scss +12 -0
  372. package/template/src/ui/root/beforeDashboard/seedButton/index.tsx +84 -0
  373. package/template/src/ui/root/siteTriggers/index.scss +22 -0
  374. package/template/src/ui/root/siteTriggers/index.tsx +94 -0
  375. package/template/src/ui/root/siteTriggers/triggerVercelDeploy.ts +37 -0
  376. package/template/src/ui/rowLabels/animation.tsx +27 -0
  377. package/template/src/ui/rowLabels/atomic/index.scss +62 -0
  378. package/template/src/ui/rowLabels/atomic/index.tsx +96 -0
  379. package/template/src/ui/rowLabels/color.tsx +33 -0
  380. package/template/src/ui/rowLabels/designToken.tsx +30 -0
  381. package/template/src/ui/rowLabels/icon.tsx +32 -0
  382. package/template/src/ui/rowLabels/shortcut/index.scss +21 -0
  383. package/template/src/ui/rowLabels/shortcut/index.tsx +30 -0
  384. package/template/src/ui/rowLabels/simpleText.tsx +41 -0
  385. package/template/src/utilities/deepMerge.ts +30 -0
  386. package/template/src/utilities/extractSVG.ts +9 -0
  387. package/template/src/utilities/format/toKebabCase.ts +79 -0
  388. package/template/src/utilities/format/toTitleCase.ts +47 -0
  389. package/template/src/utilities/formatDurationWithTokens.ts +56 -0
  390. package/template/src/utilities/generateMetaData.ts +45 -0
  391. package/template/src/utilities/generatePreviewPath.ts +43 -0
  392. package/template/src/utilities/get/cache/getAtomicActions.ts +48 -0
  393. package/template/src/utilities/get/cache/getAtomicClasses.ts +20 -0
  394. package/template/src/utilities/get/cache/getDesignSet.ts +15 -0
  395. package/template/src/utilities/get/cache/getFooter.ts +17 -0
  396. package/template/src/utilities/get/cache/getFormSubmissions.ts +17 -0
  397. package/template/src/utilities/get/cache/getForms.ts +43 -0
  398. package/template/src/utilities/get/cache/getHeader.ts +17 -0
  399. package/template/src/utilities/get/cache/getIcon.ts +51 -0
  400. package/template/src/utilities/get/cache/getImage.ts +20 -0
  401. package/template/src/utilities/get/cache/getPage.ts +35 -0
  402. package/template/src/utilities/get/cache/getPages.ts +24 -0
  403. package/template/src/utilities/get/cache/getShortcutSet.ts +17 -0
  404. package/template/src/utilities/get/cache/getSiteCSS.ts +17 -0
  405. package/template/src/utilities/get/cache/getSiteMetadata.ts +14 -0
  406. package/template/src/utilities/get/cache/getSitemap.ts +50 -0
  407. package/template/src/utilities/get/cache/getTracking.ts +14 -0
  408. package/template/src/utilities/get/cache/index.ts +129 -0
  409. package/template/src/utilities/get/cache/react.ts +5 -0
  410. package/template/src/utilities/get/getImageURL.ts +20 -0
  411. package/template/src/utilities/get/getMeUser.ts +22 -0
  412. package/template/src/utilities/get/getURL.ts +20 -0
  413. package/template/src/utilities/log/cache.ts +8 -0
  414. package/template/src/utilities/log/manual.ts +11 -0
  415. package/template/src/utilities/log/revalidation.ts +6 -0
  416. package/template/src/utilities/mergeTags.ts +7 -0
  417. package/template/src/utilities/propertyApplicatorUtility.ts +20 -0
  418. package/template/src/utilities/revalidateTag.ts +55 -0
  419. package/template/src/utilities/runAPF.ts +10 -0
  420. package/template/src/utilities/sanitizeData.ts +24 -0
  421. package/template/src/utilities/seedNestedRelationship.ts +5 -0
  422. package/template/tailwind.config.js +9 -0
  423. package/template/tsconfig.json +49 -0
@@ -0,0 +1,157 @@
1
+ 'use server'
2
+ import { Icon } from '@/ts/types'
3
+ import type { CollectionBeforeChangeHook } from 'payload'
4
+
5
+ export const formatSvg = async (icon: Partial<Icon>, svgData: Buffer): Promise<Partial<Icon>> => {
6
+ try {
7
+ // Dynamic imports to ensure these only load server-side
8
+ const [{ optimize }, { svgPathBbox }] = await Promise.all([import('svgo'), import('svg-path-bbox')])
9
+
10
+ const svg = svgData.toString('utf-8')
11
+ const originalSize = svgData.length
12
+
13
+ const hasTransforms = svg.includes('transform=')
14
+ const hasClipPaths = svg.includes('clip-path=') || svg.includes('<clipPath')
15
+ if (hasTransforms || hasClipPaths) {
16
+ console.warn('Unsupported SVG features:', { hasTransforms, hasClipPaths })
17
+ return icon
18
+ }
19
+
20
+ const optimized = optimize(svg, {
21
+ path: 'input.svg',
22
+ multipass: true,
23
+ plugins: [
24
+ 'preset-default',
25
+ 'convertStyleToAttrs',
26
+ 'removeDimensions',
27
+ {
28
+ name: 'removeAttrs',
29
+ params: {
30
+ attrs: [
31
+ 'fill',
32
+ 'stroke',
33
+ 'stroke-width',
34
+ 'stroke-linecap',
35
+ 'stroke-linejoin',
36
+ 'stroke-miterlimit',
37
+ 'stroke-dasharray',
38
+ 'stroke-dashoffset',
39
+ ],
40
+ },
41
+ },
42
+ { name: 'cleanupIds', params: { minify: true, remove: false } },
43
+ { name: 'mergePaths', params: { force: false, noSpaceAfterFlags: true } },
44
+ { name: 'cleanupNumericValues', params: { floatPrecision: 1, leadingZero: true } },
45
+ { name: 'removeUnknownsAndDefaults', params: { keepAriaAttrs: true, keepDataAttrs: true, keepRoleAttr: true } },
46
+ { name: 'addAttributesToSVGElement', params: { attributes: [{ fill: 'currentColor' }, { stroke: 'currentColor' }] } },
47
+ { name: 'convertTransform', params: { convertToShorts: true, degPrecision: 1, floatPrecision: 1, transformPrecision: 1 } },
48
+ {
49
+ name: 'convertPathData',
50
+ params: { floatPrecision: 1, leadingZero: true, noSpaceAfterFlags: true, removeUseless: true, straightCurves: true, transformPrecision: 1 },
51
+ },
52
+ {
53
+ name: 'sortAttrs',
54
+ params: {
55
+ order: [
56
+ 'id',
57
+ 'class',
58
+ 'style',
59
+ 'x',
60
+ 'y',
61
+ 'width',
62
+ 'height',
63
+ 'viewBox',
64
+ 'fill',
65
+ 'stroke',
66
+ 'stroke-width',
67
+ 'stroke-linecap',
68
+ 'stroke-linejoin',
69
+ 'stroke-miterlimit',
70
+ 'stroke-dasharray',
71
+ 'stroke-dashoffset',
72
+ 'd',
73
+ 'transform',
74
+ ],
75
+ },
76
+ },
77
+ ],
78
+ js2svg: { pretty: true, indent: 2, eol: 'lf' },
79
+ })
80
+
81
+ let svgStr = optimized.data
82
+
83
+ // Round viewBox coordinates to 1 decimal place
84
+ svgStr = svgStr.replace(/viewBox="([^"]+)"/g, (match, viewBox) => {
85
+ const coords = viewBox
86
+ .split(' ')
87
+ .map((coord: string) => {
88
+ return isNaN(parseFloat(coord)) ? coord : parseFloat(coord).toFixed(1)
89
+ })
90
+ .join(' ')
91
+ return `viewBox="${coords}"`
92
+ })
93
+
94
+ // Extract paths
95
+ const paths = Array.from(svgStr.matchAll(/<path[^>]*d="([^"]+)"/g))
96
+
97
+ if (paths.length) {
98
+ let minX = Infinity,
99
+ minY = Infinity,
100
+ maxX = -Infinity,
101
+ maxY = -Infinity
102
+
103
+ for (const [, d] of paths) {
104
+ try {
105
+ const [x1, y1, x2, y2] = svgPathBbox(d)
106
+ minX = Math.min(minX, x1)
107
+ minY = Math.min(minY, y1)
108
+ maxX = Math.max(maxX, x2)
109
+ maxY = Math.max(maxY, y2)
110
+ } catch (e) {
111
+ console.warn('Failed to calculate path bounds:', e)
112
+ }
113
+ }
114
+
115
+ if (minX !== Infinity && minY !== Infinity && maxX !== -Infinity && maxY !== -Infinity) {
116
+ const width = maxX - minX
117
+ const height = maxY - minY
118
+
119
+ // Square viewBox with minimal padding - just enough to center the content
120
+ const side = Math.max(width, height)
121
+ const centerX = minX + width / 2
122
+ const centerY = minY + height / 2
123
+ const newViewBox = `${(centerX - side / 2).toFixed(1)} ${(centerY - side / 2).toFixed(1)} ${side.toFixed(1)} ${side.toFixed(1)}`
124
+
125
+ // Replace or insert viewBox
126
+ svgStr = svgStr.includes('viewBox=')
127
+ ? svgStr.replace(/viewBox="[^"]+"/, `viewBox="${newViewBox}"`)
128
+ : svgStr.replace('<svg', `<svg viewBox="${newViewBox}"`)
129
+ }
130
+ }
131
+
132
+ const finalSize = Buffer.from(svgStr).length
133
+ const reduction = originalSize - finalSize
134
+ const reductionPercentage = ((reduction / originalSize) * 100).toFixed(1)
135
+ const optimizedString = `SVG optimized: ${originalSize} to ${finalSize} bytes (${reductionPercentage}% reduction)`
136
+ console.info(optimizedString)
137
+
138
+ return { ...icon, svgString: svgStr, optimized: optimizedString, filesize: finalSize }
139
+ } catch (error) {
140
+ console.error('Error processing SVG:', error)
141
+ return icon
142
+ }
143
+ }
144
+
145
+ export const formatSVGHook: CollectionBeforeChangeHook<Icon> = async ({ data, operation, req }) => {
146
+ if (operation === 'create' || operation === 'update') {
147
+ if (data?.filename && req.file) {
148
+ try {
149
+ return await formatSvg(data, req.file.data)
150
+ } catch (error) {
151
+ console.warn('Error in formatSVGHook:', error)
152
+ return data
153
+ }
154
+ }
155
+ }
156
+ return data
157
+ }
@@ -0,0 +1,53 @@
1
+ import { revalidateTag } from '@/utilities/revalidateTag'
2
+ import type { CollectionBeforeChangeHook, CollectionAfterDeleteHook } from 'payload'
3
+
4
+ /**
5
+ * Unified collection hook that handles all revalidations on document changes.
6
+ * Uses collection slug to determine which revalidation logic to apply.
7
+ */
8
+ export const revalidateCache: CollectionBeforeChangeHook = async ({ collection, data, originalDoc, context }) => {
9
+ if (context.isSeed) return
10
+ const slug = collection.slug
11
+ const active = Boolean(data?.active)
12
+ const draft = data?._status === 'draft'
13
+
14
+ switch (slug) {
15
+ case 'iconSet':
16
+ if (active) await revalidateTag('iconSet', draft)
17
+ break
18
+ case 'forms':
19
+ await revalidateTag('backend-forms')
20
+ await revalidateTag('form-submissions', data?.title)
21
+ break
22
+ case 'form-submissions':
23
+ await revalidateTag('form-submissions', data?.form)
24
+ break
25
+ case 'images':
26
+ await revalidateTag('image', originalDoc?.id)
27
+ break
28
+ case 'icon':
29
+ await revalidateTag('icon', originalDoc?.id, draft)
30
+ break
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Unified collection hook that handles all revalidations on document deletion.
36
+ * Uses collection slug to determine which revalidation logic to apply.
37
+ */
38
+ export const revalidateCacheOnDelete: CollectionAfterDeleteHook = async ({ collection, doc }) => {
39
+ const { slug: tag } = collection
40
+ switch (tag) {
41
+ case 'footer':
42
+ case 'header':
43
+ case 'iconSet':
44
+ case 'designSet':
45
+ case 'shortcutSet':
46
+ if (Boolean(doc?.active)) await revalidateTag(tag, false)
47
+ break
48
+ case 'pages':
49
+ revalidateTag(tag, false)
50
+ revalidateTag('page', doc?.href, false)
51
+ break
52
+ }
53
+ }
@@ -0,0 +1,5 @@
1
+ import sanitizeData from '@/utilities/sanitizeData'
2
+ import type { CollectionAfterReadHook } from 'payload'
3
+
4
+ // Would not recommend using this hook, as it is expensive. It is provided in case you want to more easily read recursive data from the database for a short while.
5
+ export const sanitizeAfterRead: CollectionAfterReadHook = async ({ doc }) => sanitizeData(doc)
@@ -0,0 +1,59 @@
1
+ // /////////////////////////////////////
2
+ // ONLY USE THESE HOOKS ON NON RECURSIVE FIELDS
3
+ // OTHERWISE PERFORMANCE WILL SUFFER
4
+ // /////////////////////////////////////
5
+ import type { FieldHook } from 'payload'
6
+ import type { APFunction } from '@/ts/types/apf'
7
+
8
+ export const virtualAPFBeforeChangeFieldHook: FieldHook = ({ context, value, field, originalDoc }) => {
9
+ if (!originalDoc?.id) return
10
+ const key = `${originalDoc?.id}-${field?.name?.replace(/^apf-/, '').trim()}`
11
+ if (key in context) return
12
+ context[key] = value
13
+ }
14
+
15
+ export const virtualAPFAfterReadFieldHook: FieldHook = () => false
16
+
17
+ /**
18
+ * Field hook that marks a document as modified when arrays change (shallow comparison).
19
+ * Only checks array length.
20
+ *
21
+ * @fields array
22
+ * @param apf - The type of change to set in context. {@link APFunctions}
23
+ */
24
+ export const onArraySetAPFShallow =
25
+ (apf: APFunction[]): FieldHook =>
26
+ ({ previousValue, value, context, originalDoc }) => {
27
+ if (!originalDoc?.id) return
28
+
29
+ const hasLengthChange = value?.length !== previousValue?.length
30
+ if (!hasLengthChange) return
31
+
32
+ for (const apfFunction of apf) {
33
+ const contextKey = `${originalDoc.id}-${apfFunction}`
34
+ if (context[contextKey]) continue // Respect context values set by other apf before validate hooks.
35
+ context[contextKey] = true
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Field hook that marks a document as modified when the upload field changes.
41
+ *
42
+ * @fields upload
43
+ * @param apf - The type of change to set in context. {@link APFunctions}
44
+ */
45
+ export const onUploadSetAPF =
46
+ (apf: APFunction[]): FieldHook =>
47
+ ({ previousValue, value, context, originalDoc }) => {
48
+ if (!originalDoc?.id) return
49
+
50
+ const previousId = previousValue?.id
51
+ const currentId = value?.id
52
+ if (previousId === currentId) return
53
+
54
+ for (const apfFunction of apf) {
55
+ const contextKey = `${originalDoc.id}-${apfFunction}`
56
+ if (context[contextKey]) continue
57
+ context[contextKey] = true
58
+ }
59
+ }
@@ -0,0 +1,23 @@
1
+ import type { FieldHook } from 'payload'
2
+
3
+ export const formatSlug = (val: string): string =>
4
+ val
5
+ .replace(/ /g, '-')
6
+ .replace(/[^\w-]+/g, '')
7
+ .toLowerCase()
8
+
9
+ export const formatSlugHook =
10
+ (fallback: string): FieldHook =>
11
+ ({ data, operation, value }) => {
12
+ if (typeof value === 'string') return formatSlug(value)
13
+
14
+ if (operation === 'create' || !data?.slug) {
15
+ const fallbackData = data?.[fallback] || data?.[fallback]
16
+
17
+ if (fallbackData && typeof fallbackData === 'string') {
18
+ return formatSlug(fallbackData)
19
+ }
20
+ }
21
+
22
+ return value
23
+ }
@@ -0,0 +1,6 @@
1
+ import type { FieldHook } from 'payload'
2
+
3
+ export const updateHrefHook: FieldHook = ({ previousValue, data }) => {
4
+ const lastBreadcrumbUrl = data?.breadcrumbs[data?.breadcrumbs?.length - 1]?.url
5
+ if (previousValue !== lastBreadcrumbUrl) return lastBreadcrumbUrl
6
+ }
@@ -0,0 +1,5 @@
1
+ import type { FieldHook } from 'payload'
2
+
3
+ export const updatePublishedAtHook: FieldHook = ({ operation }) => {
4
+ if (operation === 'update') return new Date()
5
+ }
@@ -0,0 +1,69 @@
1
+ import { createStore } from 'zustand'
2
+ import { baseSlice } from './slices/base'
3
+ import { persist } from 'zustand/middleware'
4
+ import { dynamicSlice } from './slices/dynamic'
5
+ import { consentSlice, STORAGE_KEYS } from './slices/consent'
6
+ import type { AtomicStore, AtomicStoreInitialState } from '@/ts/types'
7
+
8
+ const safeStorageOperation = <T>(operation: () => T, fallback: T): T => {
9
+ try {
10
+ return operation()
11
+ } catch (error) {
12
+ console.error('Storage operation failed:', error)
13
+ return fallback
14
+ }
15
+ }
16
+
17
+ //TODO: Implement the initialState, so actions can be site wide, rather than by page. Though this requires many backend changes.
18
+ export const createAtomicStore = (initialState: AtomicStoreInitialState) => {
19
+ return createStore<AtomicStore>()(
20
+ persist(
21
+ (...a) => ({
22
+ ...baseSlice(...a),
23
+ ...consentSlice(...a),
24
+ ...dynamicSlice(...a),
25
+ }),
26
+ {
27
+ name: 'atomic-store',
28
+ partialize: (state) => ({
29
+ persisted: state.persisted,
30
+ preferences: state.preferences,
31
+ hasConsented: state.hasConsented,
32
+ previouslyConsented: state.previouslyConsented,
33
+ }),
34
+ onRehydrateStorage: () => (state) => {
35
+ if (!state) return
36
+ state.setHydrated(true)
37
+
38
+ const local = safeStorageOperation(() => localStorage.getItem(STORAGE_KEYS.COOKIE_CONSENT), null)
39
+ const session = safeStorageOperation(() => sessionStorage.getItem(STORAGE_KEYS.COOKIE_CONSENT), null)
40
+ // Session storage takes precedence (for session-only declines)
41
+ if (session === 'false') state.declineCookies()
42
+
43
+ // Check localStorage for persistent consent
44
+ if (local === 'true') {
45
+ const storedPreferences = safeStorageOperation(() => localStorage.getItem(STORAGE_KEYS.COOKIE_PREFERENCES), null)
46
+
47
+ if (storedPreferences) {
48
+ try {
49
+ const preferences = JSON.parse(storedPreferences)
50
+ state.acceptCookies(preferences)
51
+ } catch (error) {
52
+ console.error('Error parsing stored preferences:', error)
53
+ state.acceptCookies()
54
+ }
55
+ } else state.acceptCookies()
56
+ }
57
+ },
58
+ //Ensures there are no issues with conflicting versions of the store when editing pages in admin.
59
+ version: initialState.version,
60
+ migrate: (persistedState, version) => {
61
+ if (version !== initialState.version && typeof persistedState === 'object' && persistedState !== null && 'persisted' in persistedState) {
62
+ delete persistedState.persisted
63
+ }
64
+ return persistedState
65
+ },
66
+ },
67
+ ),
68
+ )
69
+ }
@@ -0,0 +1,20 @@
1
+ 'use client'
2
+ import { useStore } from 'zustand'
3
+ import { createContext, useState, useContext } from 'react'
4
+ import { createAtomicStore } from '@/hooks/frontEnd/atomicStore/create'
5
+ import type { AtomicStore, AtomicStoreProviderProps } from '@/ts/types'
6
+
7
+ export type AtomicStoreApi = ReturnType<typeof createAtomicStore>
8
+ export const AtomicStoreContext = createContext<AtomicStoreApi | undefined>(undefined)
9
+
10
+ export const AtomicStoreProvider = ({ children, initialState }: AtomicStoreProviderProps) => {
11
+ const [store] = useState(() => createAtomicStore(initialState))
12
+
13
+ return <AtomicStoreContext.Provider value={store}>{children}</AtomicStoreContext.Provider>
14
+ }
15
+
16
+ export const useAtomicStore = <T,>(selector: (store: AtomicStore) => T): T => {
17
+ const atomicStoreContext = useContext(AtomicStoreContext)
18
+ if (!atomicStoreContext) throw new Error(`useAtomicStore must be used within AtomicStoreProvider`)
19
+ return useStore(atomicStoreContext, selector)
20
+ }
@@ -0,0 +1,7 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AtomicStore, BaseSlice } from '@/ts/types'
3
+
4
+ export const baseSlice: StateCreator<AtomicStore, [], [], BaseSlice> = (set) => ({
5
+ hydrated: false,
6
+ setHydrated: (s) => set({ hydrated: s }),
7
+ })
@@ -0,0 +1,76 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AtomicStore, ConsentPreferences, ConsentSlice } from '@/ts/types'
3
+
4
+ const COOKIE_EXPIRY_YEARS = 1
5
+ export const STORAGE_KEYS = {
6
+ COOKIE_CONSENT: 'cookieConsent',
7
+ COOKIE_PREFERENCES: 'cookiePreferences',
8
+ } as const
9
+
10
+ const DEFAULT_PREFERENCES: ConsentPreferences = {
11
+ functional: true,
12
+ security: true,
13
+ analytics: false,
14
+ marketing: false,
15
+ userData: false,
16
+ adPersonalization: false,
17
+ contentPersonalization: false,
18
+ }
19
+
20
+ // Utility functions
21
+ const setCookie = (name: string, value: string, expiryYears: number = COOKIE_EXPIRY_YEARS) => {
22
+ const date = new Date()
23
+ date.setFullYear(date.getFullYear() + expiryYears)
24
+ document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/; SameSite=Lax; Secure`
25
+ }
26
+
27
+ const safeStorageOperation = <T>(operation: () => T, fallback: T): T => {
28
+ try {
29
+ return operation()
30
+ } catch (error) {
31
+ console.error('Storage operation failed:', error)
32
+ return fallback
33
+ }
34
+ }
35
+
36
+ export const consentSlice: StateCreator<AtomicStore, [], [], ConsentSlice> = (set) => ({
37
+ hasConsented: null,
38
+ previouslyConsented: null,
39
+ preferences: DEFAULT_PREFERENCES,
40
+ setPreference: (category, value) => {
41
+ set((state) => ({ preferences: { ...state.preferences, [category]: category === 'functional' || category === 'security' ? true : value } }))
42
+ },
43
+ acceptCookies: (preferences) => {
44
+ const newPreferences = { ...DEFAULT_PREFERENCES, ...preferences, functional: true, security: true }
45
+
46
+ // Batch storage operations
47
+ safeStorageOperation(() => {
48
+ setCookie(STORAGE_KEYS.COOKIE_CONSENT, 'true')
49
+ localStorage.setItem(STORAGE_KEYS.COOKIE_CONSENT, 'true')
50
+ localStorage.setItem(STORAGE_KEYS.COOKIE_PREFERENCES, JSON.stringify(newPreferences))
51
+ sessionStorage.removeItem(STORAGE_KEYS.COOKIE_CONSENT)
52
+ }, null)
53
+
54
+ set({ hasConsented: true, previouslyConsented: true, preferences: newPreferences })
55
+ },
56
+ declineCookies: () => {
57
+ const declinedPreferences = {
58
+ ...DEFAULT_PREFERENCES,
59
+ // Only functional and security remain true
60
+ analytics: false,
61
+ marketing: false,
62
+ userData: false,
63
+ adPersonalization: false,
64
+ contentPersonalization: false,
65
+ }
66
+
67
+ // Batch storage operations
68
+ safeStorageOperation(() => {
69
+ localStorage.removeItem(STORAGE_KEYS.COOKIE_CONSENT)
70
+ localStorage.removeItem(STORAGE_KEYS.COOKIE_PREFERENCES)
71
+ sessionStorage.setItem(STORAGE_KEYS.COOKIE_CONSENT, 'false')
72
+ }, null)
73
+
74
+ set({ previouslyConsented: true, hasConsented: false, preferences: declinedPreferences })
75
+ },
76
+ })
@@ -0,0 +1,51 @@
1
+ import { StateCreator } from 'zustand'
2
+ import type { AtomicStore, DynamicSlice } from '@/ts/types'
3
+
4
+ export const dynamicSlice: StateCreator<AtomicStore, [], [], DynamicSlice> = (set, get) => ({
5
+ persisted: {},
6
+ memory: {},
7
+ setValue: (key, value, persisted) => {
8
+ if (!get().hydrated) return
9
+ if (persisted) set((state) => ({ persisted: { ...state.persisted, [key]: value } }))
10
+ else set((state) => ({ memory: { ...state.memory, [key]: value } }))
11
+ },
12
+ getValue: (key, persisted) => {
13
+ return persisted ? get().persisted[key] : get().memory[key]
14
+ },
15
+ removeValue: (key, persisted) => {
16
+ if (persisted) {
17
+ set((state) => {
18
+ const { [key]: _, ...rest } = state.persisted
19
+ return { persisted: rest }
20
+ })
21
+ } else {
22
+ set((state) => {
23
+ const { [key]: _, ...rest } = state.memory
24
+ return { memory: rest }
25
+ })
26
+ }
27
+ },
28
+ })
29
+
30
+ /* clearStorage: (persisted) => {
31
+ if (persisted) set({ persisted: {} })
32
+ else set({ memory: {} })
33
+ },
34
+ setMultiple: (entries) => {
35
+ const persistedUpdates: Record<string, ImplementedStorageTypes> = {}
36
+ const memoryUpdates: Record<string, ImplementedStorageTypes> = {}
37
+ entries.forEach(({ key, value, persisted }) => {
38
+ if (persisted) persistedUpdates[key] = value
39
+ else memoryUpdates[key] = value
40
+ })
41
+ if (Object.keys(persistedUpdates).length) set((state) => ({ persisted: { ...state.persisted, ...persistedUpdates } }))
42
+ if (Object.keys(memoryUpdates).length) set((state) => ({ memory: { ...state.memory, ...memoryUpdates } }))
43
+ },
44
+ getMultiple: (keys) => {
45
+ const state = get()
46
+ const result: Record<string, ImplementedStorageTypes> = {}
47
+ keys.forEach(({ key, persisted }) => {
48
+ result[key] = persisted ? state.persisted[key] : state.memory[key]
49
+ })
50
+ return result
51
+ }, */
@@ -0,0 +1,14 @@
1
+ import { AttFunction } from '@/ts/types/actions'
2
+
3
+ export const AttBoolToDA: AttFunction<'AttBoolToDA'> = ({ key, persisted, initialValue, changeKey, context }) => {
4
+ const { getValue, hydrated } = context.atomicStore
5
+ if (!hydrated) {
6
+ if (initialValue) return { [`data-${changeKey || key}`]: '' }
7
+ else return
8
+ } //Prevents SSR hydration errors
9
+
10
+ const storedValue = getValue(key, persisted)
11
+ const newValue = storedValue && typeof storedValue === 'boolean' ? storedValue : initialValue
12
+ if (newValue) return { [`data-${changeKey || key}`]: '' }
13
+ else return
14
+ }
@@ -0,0 +1,12 @@
1
+ import { z } from '@/ts/zap'
2
+
3
+ export const BoolToDASchema = z.ap.add(
4
+ z.object({
5
+ type: z.literal('AttBoolToDA'),
6
+ key: z.string(),
7
+ changeKey: z.string().nullable().optional(),
8
+ persisted: z.boolean().nullable().optional(),
9
+ initialValue: z.boolean().nullable().optional(),
10
+ }),
11
+ { id: 'AttBoolToDA' },
12
+ )
@@ -0,0 +1,34 @@
1
+ import { AttFunction } from '@/ts/types'
2
+
3
+ export const AttCCToDA: AttFunction<'AttCCToDA'> = ({
4
+ listen,
5
+ changeKey,
6
+ context: {
7
+ atomicStore: { preferences, hasConsented, previouslyConsented },
8
+ },
9
+ }) => {
10
+ let returns: Record<string, string> | undefined
11
+
12
+ switch (listen.listen) {
13
+ case 'preference':
14
+ if (!listen.key) return
15
+ const checked = preferences?.[listen.key]
16
+ if (checked) returns = { [`data-${changeKey || listen.key}`]: '' }
17
+ break
18
+ case 'accept':
19
+ if (hasConsented === true) returns = { [`data-${changeKey || 'accepted'}`]: '' }
20
+ break
21
+ case 'decline':
22
+ if (hasConsented === false) returns = { [`data-${changeKey || 'declined'}`]: '' }
23
+ break
24
+ case 'hasConsented':
25
+ if (changeKey) returns = { [`data-${changeKey}`]: hasConsented ? 'accepted' : 'declined' }
26
+ else returns = { [`data-${hasConsented ? `accepted` : `declined`}`]: '' }
27
+ break
28
+ case 'previouslyConsented':
29
+ if (changeKey) returns = { [`data-${changeKey}`]: previouslyConsented ? 'accepted' : 'declined' }
30
+ else returns = { [`data-${previouslyConsented ? `accepted` : `declined`}`]: '' }
31
+ break
32
+ }
33
+ return returns
34
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from '@/ts/zap'
2
+ import { cookieConsentKeys } from '@/fields/actions/strict/registry/cookieConsent'
3
+
4
+ export const CCtoDASchema = z.ap.add(
5
+ z.object({
6
+ type: z.literal('AttCCToDA'),
7
+ listen: z.discriminatedUnion('listen', [
8
+ z.object({ listen: z.literal('preference'), key: cookieConsentKeys }),
9
+ z.object({ listen: z.literal('accept') }),
10
+ z.object({ listen: z.literal('decline') }),
11
+ z.object({ listen: z.literal('hasConsented') }),
12
+ z.object({ listen: z.literal('previouslyConsented') }),
13
+ ]),
14
+ changeKey: z.string().nullable().optional(),
15
+ }),
16
+ { id: 'AttCCToDA' },
17
+ )
@@ -0,0 +1,22 @@
1
+ import { AttFunction, ImplementedStorageTypes } from '@/ts/types'
2
+
3
+ export const AttFormErrorToDA: AttFunction<'AttFormErrorToDA'> = ({ key, inputName = 'form', context }) => {
4
+ if (!context.fullFormContext) {
5
+ console.error('AttFormErrorToDA: fullFormContext is undefined')
6
+ return
7
+ }
8
+ const { getValue, hydrated } = context.atomicStore
9
+
10
+ if (!hydrated) return //Prevents SSR hydration errors
11
+ if (!key) return
12
+ const inputKey = inputName || 'form'
13
+
14
+ if (context.fullFormContext.formResponse?.success) return
15
+
16
+ const storedValue: ImplementedStorageTypes = getValue(`${key}-response`, false)
17
+ if (!storedValue || typeof storedValue !== 'object') return
18
+
19
+ const errorMessage = storedValue[inputKey]
20
+ if (!errorMessage) return
21
+ return { [`data-error`]: errorMessage || '' }
22
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from '@/ts/zap'
2
+
3
+ export const FormErrorToDASchema = z.ap.add(
4
+ z.object({
5
+ type: z.literal('AttFormErrorToDA'),
6
+ key: z.string(),
7
+ inputName: z.string().nullable().optional(),
8
+ }),
9
+ { id: 'AttFormErrorToDA' },
10
+ )