create-nextblock 0.16.1 → 0.16.3

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 (264) hide show
  1. package/docker-template/.dockerignore +1 -1
  2. package/libs/db/tsconfig.lib.json +3 -3
  3. package/libs/editor/tsconfig.lib.json +3 -3
  4. package/libs/ui/tsconfig.lib.json +3 -3
  5. package/libs/utils/tsconfig.json +3 -3
  6. package/package.json +50 -50
  7. package/project.json +19 -19
  8. package/templates/nextblock-template/.dockerignore +1 -1
  9. package/templates/nextblock-template/.swcrc +30 -30
  10. package/templates/nextblock-template/AGENTS.md +9 -9
  11. package/templates/nextblock-template/CLAUDE.md +1 -1
  12. package/templates/nextblock-template/app/(auth-pages)/layout.tsx +9 -9
  13. package/templates/nextblock-template/app/(auth-pages)/post-sign-in/page.tsx +27 -27
  14. package/templates/nextblock-template/app/.well-known/ucp/route.ts +16 -16
  15. package/templates/nextblock-template/app/ToasterProvider.tsx +26 -26
  16. package/templates/nextblock-template/app/[slug]/pageClientActions.ts +7 -7
  17. package/templates/nextblock-template/app/actions/contactSellerActions.test.ts +280 -280
  18. package/templates/nextblock-template/app/actions/contactSellerActions.ts +222 -222
  19. package/templates/nextblock-template/app/actions/email-retry.test.ts +62 -62
  20. package/templates/nextblock-template/app/actions/email.ts +241 -241
  21. package/templates/nextblock-template/app/actions/formActions.ts +245 -245
  22. package/templates/nextblock-template/app/actions/interactions.ts +489 -489
  23. package/templates/nextblock-template/app/actions/threadActions.ts +166 -166
  24. package/templates/nextblock-template/app/actions/visibilityActions.ts +210 -210
  25. package/templates/nextblock-template/app/api/ai/seo/alt-text/route.ts +221 -221
  26. package/templates/nextblock-template/app/api/ai/seo/metadata/route.ts +186 -186
  27. package/templates/nextblock-template/app/api/checkout/freemius/sync/route.ts +29 -29
  28. package/templates/nextblock-template/app/api/checkout/route.ts +162 -162
  29. package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +4 -4
  30. package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +4542 -2904
  31. package/templates/nextblock-template/app/api/mcp/route.ts +415 -415
  32. package/templates/nextblock-template/app/api/media/record/route.ts +160 -160
  33. package/templates/nextblock-template/app/api/search/route.ts +43 -43
  34. package/templates/nextblock-template/app/api/view/route.ts +114 -114
  35. package/templates/nextblock-template/app/api/visual-editing/block-draft/route.ts +47 -47
  36. package/templates/nextblock-template/app/api/visual-editing/product-draft/route.ts +47 -47
  37. package/templates/nextblock-template/app/auth/callback/route.ts +31 -31
  38. package/templates/nextblock-template/app/cart/page.tsx +7 -7
  39. package/templates/nextblock-template/app/checkout/UcpCartHydrator.tsx +20 -20
  40. package/templates/nextblock-template/app/checkout/page.tsx +57 -57
  41. package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +558 -558
  42. package/templates/nextblock-template/app/cms/blocks/components/BlockEditorModal.tsx +241 -241
  43. package/templates/nextblock-template/app/cms/blocks/components/MediaLibraryModal.tsx +149 -149
  44. package/templates/nextblock-template/app/cms/blocks/editors/FormBlockEditor.tsx +304 -304
  45. package/templates/nextblock-template/app/cms/blocks/editors/ImageBlockEditor.tsx +406 -406
  46. package/templates/nextblock-template/app/cms/components/ContactReminderBanner.tsx +75 -75
  47. package/templates/nextblock-template/app/cms/components/CortexAiActiveContext.tsx +23 -23
  48. package/templates/nextblock-template/app/cms/components/CortexAiPageContext.tsx +58 -58
  49. package/templates/nextblock-template/app/cms/components/FeatureImageField.tsx +254 -254
  50. package/templates/nextblock-template/app/cms/components/FeedbackModal.tsx +36 -36
  51. package/templates/nextblock-template/app/cms/components/PaymentsReminderBanner.tsx +58 -58
  52. package/templates/nextblock-template/app/cms/components/SeoScoreBadge.tsx +40 -0
  53. package/templates/nextblock-template/app/cms/components/TablePagination.tsx +136 -0
  54. package/templates/nextblock-template/app/cms/components/VisibilityBadge.tsx +62 -62
  55. package/templates/nextblock-template/app/cms/components/VisibilityControl.tsx +542 -542
  56. package/templates/nextblock-template/app/cms/coupons/[id]/edit/page.tsx +16 -16
  57. package/templates/nextblock-template/app/cms/coupons/page.tsx +16 -16
  58. package/templates/nextblock-template/app/cms/dashboard/actions.ts +228 -228
  59. package/templates/nextblock-template/app/cms/dashboard/components/DashboardComponents.tsx +200 -200
  60. package/templates/nextblock-template/app/cms/inquiries/actions.ts +66 -66
  61. package/templates/nextblock-template/app/cms/inquiries/page.tsx +12 -12
  62. package/templates/nextblock-template/app/cms/interactions/page.tsx +12 -12
  63. package/templates/nextblock-template/app/cms/layout.tsx +101 -101
  64. package/templates/nextblock-template/app/cms/media/components/FolderNavigator.tsx +273 -273
  65. package/templates/nextblock-template/app/cms/media/components/FolderTree.tsx +122 -122
  66. package/templates/nextblock-template/app/cms/media/components/MediaGridClient.tsx +69 -69
  67. package/templates/nextblock-template/app/cms/messages/MessagesClient.tsx +661 -661
  68. package/templates/nextblock-template/app/cms/messages/actions.ts +404 -404
  69. package/templates/nextblock-template/app/cms/messages/loadInbox.ts +333 -333
  70. package/templates/nextblock-template/app/cms/messages/page.tsx +87 -87
  71. package/templates/nextblock-template/app/cms/messages/require-admin.ts +37 -37
  72. package/templates/nextblock-template/app/cms/navigation/components/NavigationMenuDnd.tsx +3 -3
  73. package/templates/nextblock-template/app/cms/pages/components/PageForm.tsx +649 -649
  74. package/templates/nextblock-template/app/cms/pages/page.tsx +273 -227
  75. package/templates/nextblock-template/app/cms/posts/[id]/edit/page.tsx +2 -0
  76. package/templates/nextblock-template/app/cms/posts/components/PostForm.tsx +624 -618
  77. package/templates/nextblock-template/app/cms/posts/page.tsx +251 -194
  78. package/templates/nextblock-template/app/cms/products/[id]/edit/page.tsx +370 -370
  79. package/templates/nextblock-template/app/cms/products/attributes/page.tsx +12 -12
  80. package/templates/nextblock-template/app/cms/products/inventory/page.tsx +13 -13
  81. package/templates/nextblock-template/app/cms/products/productFormData.ts +133 -133
  82. package/templates/nextblock-template/app/cms/products/settings/page.tsx +5 -5
  83. package/templates/nextblock-template/app/cms/revisions/actions.ts +332 -332
  84. package/templates/nextblock-template/app/cms/revisions/service.test.ts +498 -498
  85. package/templates/nextblock-template/app/cms/revisions/service.ts +569 -569
  86. package/templates/nextblock-template/app/cms/revisions/utils.ts +304 -304
  87. package/templates/nextblock-template/app/cms/settings/cortex-ai/CortexAiSettingsClient.tsx +948 -948
  88. package/templates/nextblock-template/app/cms/settings/cortex-ai/McpServerSettingsCard.tsx +628 -628
  89. package/templates/nextblock-template/app/cms/settings/cortex-ai/mcp-actions.ts +230 -230
  90. package/templates/nextblock-template/app/cms/settings/cortex-ai/require-admin.ts +34 -34
  91. package/templates/nextblock-template/app/cms/settings/currencies/actions.ts +331 -331
  92. package/templates/nextblock-template/app/cms/settings/currencies/page.tsx +494 -494
  93. package/templates/nextblock-template/app/cms/settings/email/components/EmailForm.tsx +227 -227
  94. package/templates/nextblock-template/app/cms/settings/extra-translations/ExtraTranslationsWorkspace.tsx +767 -767
  95. package/templates/nextblock-template/app/cms/settings/extra-translations/actions.ts +276 -276
  96. package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +93 -93
  97. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeEditor.tsx +382 -382
  98. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeManager.tsx +267 -267
  99. package/templates/nextblock-template/app/cms/settings/global-css/page.tsx +40 -40
  100. package/templates/nextblock-template/app/cms/settings/global-css/theme-actions.ts +259 -259
  101. package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +7 -7
  102. package/templates/nextblock-template/app/cms/settings/logos/components/BrandingSettingsForm.tsx +339 -339
  103. package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +8 -8
  104. package/templates/nextblock-template/app/cms/settings/seo/RedirectsCard.tsx +514 -514
  105. package/templates/nextblock-template/app/cms/settings/seo/RobotsCard.tsx +529 -529
  106. package/templates/nextblock-template/app/cms/settings/seo/SeoSettingsClient.tsx +57 -57
  107. package/templates/nextblock-template/app/cms/settings/seo/actions.ts +448 -448
  108. package/templates/nextblock-template/app/cms/settings/seo/mappers.ts +93 -93
  109. package/templates/nextblock-template/app/cms/settings/seo/page.tsx +46 -46
  110. package/templates/nextblock-template/app/cms/settings/seo/require-admin.ts +47 -47
  111. package/templates/nextblock-template/app/cms/settings/site-scripts/page.tsx +51 -51
  112. package/templates/nextblock-template/app/cms/settings/taxes/page.tsx +21 -21
  113. package/templates/nextblock-template/app/cms/shipping/page.tsx +20 -20
  114. package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +12 -12
  115. package/templates/nextblock-template/app/layout.tsx +671 -671
  116. package/templates/nextblock-template/app/lib/seo.ts +319 -319
  117. package/templates/nextblock-template/app/lib/ucp/protocol.ts +190 -190
  118. package/templates/nextblock-template/app/lib/ucp/server.test.ts +56 -56
  119. package/templates/nextblock-template/app/product/[slug]/page.tsx +502 -502
  120. package/templates/nextblock-template/app/profile/ProfilePageHeader.tsx +16 -16
  121. package/templates/nextblock-template/app/profile/ProfilePageMissingState.tsx +9 -9
  122. package/templates/nextblock-template/app/profile/account-links.ts +22 -22
  123. package/templates/nextblock-template/app/profile/orders/CustomerOrdersPageClient.tsx +124 -124
  124. package/templates/nextblock-template/app/profile/orders/page.tsx +19 -19
  125. package/templates/nextblock-template/app/profile/password/PasswordSettingsPageClient.tsx +128 -128
  126. package/templates/nextblock-template/app/profile/password/actions.ts +59 -59
  127. package/templates/nextblock-template/app/profile/password/page.tsx +27 -27
  128. package/templates/nextblock-template/app/providers.tsx +96 -96
  129. package/templates/nextblock-template/app/robots.ts +123 -123
  130. package/templates/nextblock-template/app/thread/ThreadView.tsx +164 -164
  131. package/templates/nextblock-template/app/thread/[token]/route.ts +57 -57
  132. package/templates/nextblock-template/app/thread/layout.tsx +15 -15
  133. package/templates/nextblock-template/app/thread/page.tsx +98 -98
  134. package/templates/nextblock-template/app/ucp/v1/carts/[id]/cancel/route.ts +38 -38
  135. package/templates/nextblock-template/app/ucp/v1/carts/[id]/route.ts +68 -68
  136. package/templates/nextblock-template/app/ucp/v1/carts/route.ts +35 -35
  137. package/templates/nextblock-template/app/ucp/v1/catalog/lookup/route.ts +35 -35
  138. package/templates/nextblock-template/app/ucp/v1/catalog/product/route.ts +35 -35
  139. package/templates/nextblock-template/app/ucp/v1/catalog/search/route.ts +34 -34
  140. package/templates/nextblock-template/components/BlockRenderer.tsx +312 -312
  141. package/templates/nextblock-template/components/CartDrawerLoader.tsx +7 -7
  142. package/templates/nextblock-template/components/CartTranslator.tsx +210 -210
  143. package/templates/nextblock-template/components/ContactSellerSection.tsx +188 -188
  144. package/templates/nextblock-template/components/DeferredCartDrawer.tsx +23 -23
  145. package/templates/nextblock-template/components/DeferredCartTranslator.tsx +51 -51
  146. package/templates/nextblock-template/components/DeferredGlobalSearch.tsx +68 -68
  147. package/templates/nextblock-template/components/DeferredGoogleTagManager.tsx +70 -70
  148. package/templates/nextblock-template/components/DeferredSpeedInsights.tsx +69 -69
  149. package/templates/nextblock-template/components/FooterNavigation.tsx +32 -32
  150. package/templates/nextblock-template/components/GlobalSearch.tsx +557 -557
  151. package/templates/nextblock-template/components/Header.tsx +38 -38
  152. package/templates/nextblock-template/components/HtmlScriptExecutor.tsx +47 -47
  153. package/templates/nextblock-template/components/LanguageSwitcher.tsx +2 -2
  154. package/templates/nextblock-template/components/PostCommentsSection.tsx +378 -378
  155. package/templates/nextblock-template/components/ProductReviewsSection.tsx +426 -426
  156. package/templates/nextblock-template/components/SiteScripts.tsx +56 -56
  157. package/templates/nextblock-template/components/StaffReplies.tsx +102 -102
  158. package/templates/nextblock-template/components/blocks/PostCardSkeleton.tsx +12 -12
  159. package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +12 -12
  160. package/templates/nextblock-template/components/blocks/PostsGridClient.tsx +48 -48
  161. package/templates/nextblock-template/components/blocks/TestimonialBlock.tsx +9 -9
  162. package/templates/nextblock-template/components/blocks/ecommerceRendererLoaders.ts +23 -23
  163. package/templates/nextblock-template/components/blocks/publicRendererLoaders.ts +25 -25
  164. package/templates/nextblock-template/components/blocks/renderers/ButtonBlockRenderer.tsx +92 -92
  165. package/templates/nextblock-template/components/blocks/renderers/CartBlockRenderer.tsx +18 -18
  166. package/templates/nextblock-template/components/blocks/renderers/CheckoutBlockRenderer.tsx +20 -20
  167. package/templates/nextblock-template/components/blocks/renderers/FeaturedProductBlockRenderer.tsx +25 -25
  168. package/templates/nextblock-template/components/blocks/renderers/FormBlockRenderer.tsx +385 -385
  169. package/templates/nextblock-template/components/blocks/renderers/PostsGridBlockRenderer.tsx +24 -24
  170. package/templates/nextblock-template/components/blocks/renderers/ProductDetailsBlockRenderer.tsx +157 -157
  171. package/templates/nextblock-template/components/blocks/renderers/ProductGridBlockRenderer.tsx +34 -34
  172. package/templates/nextblock-template/components/blocks/renderers/SectionBlockRenderer.tsx +612 -612
  173. package/templates/nextblock-template/components/blocks/renderers/TestimonialBlockRenderer.tsx +57 -57
  174. package/templates/nextblock-template/components/blocks/renderers/inline/AlertWidgetRenderer.tsx +2 -2
  175. package/templates/nextblock-template/components/blocks/renderers/inline/CtaWidgetRenderer.tsx +2 -2
  176. package/templates/nextblock-template/components/blocks/types.ts +7 -7
  177. package/templates/nextblock-template/components/commerce/PaymentReadinessBoundary.tsx +32 -32
  178. package/templates/nextblock-template/components/env-var-warning.tsx +3 -3
  179. package/templates/nextblock-template/components/form-message.tsx +32 -32
  180. package/templates/nextblock-template/components/seo/GenerateMetaButton.tsx +137 -137
  181. package/templates/nextblock-template/components/seo/PageSeoAuditSection.tsx +251 -244
  182. package/templates/nextblock-template/components/seo/SeoAuditPanel.tsx +749 -749
  183. package/templates/nextblock-template/components/seo/SeoIssueList.tsx +195 -195
  184. package/templates/nextblock-template/components/seo/SeoScoreDial.tsx +144 -144
  185. package/templates/nextblock-template/components/seo/SocialPreview.tsx +243 -243
  186. package/templates/nextblock-template/components/seo/SocialPreviewDialog.tsx +110 -110
  187. package/templates/nextblock-template/components/submit-button.tsx +23 -23
  188. package/templates/nextblock-template/components/theme-icon.tsx +78 -78
  189. package/templates/nextblock-template/components/theme-switcher.tsx +85 -85
  190. package/templates/nextblock-template/context/AuthContext.tsx +23 -23
  191. package/templates/nextblock-template/context/ThemeCatalogContext.tsx +44 -44
  192. package/templates/nextblock-template/docs/01-PROJECT-OVERVIEW.md +94 -94
  193. package/templates/nextblock-template/docs/03-CMS-AND-EDITOR.md +77 -77
  194. package/templates/nextblock-template/docs/13-STAYING-UP-TO-DATE.md +372 -372
  195. package/templates/nextblock-template/docs/14-MESSAGES-INBOX.md +309 -309
  196. package/templates/nextblock-template/docs/README.md +42 -42
  197. package/templates/nextblock-template/docs/TECHNICAL_SPECIFICATION.md +12506 -12506
  198. package/templates/nextblock-template/hooks/use-hotkeys.ts +21 -21
  199. package/templates/nextblock-template/hooks/useGlobalSearch.ts +101 -101
  200. package/templates/nextblock-template/index.d.ts +7 -7
  201. package/templates/nextblock-template/lib/auth-redirects.ts +46 -46
  202. package/templates/nextblock-template/lib/blocks/blockColors.test.ts +134 -134
  203. package/templates/nextblock-template/lib/blocks/blockColors.ts +175 -175
  204. package/templates/nextblock-template/lib/blocks/blockRegistry.ts +761 -761
  205. package/templates/nextblock-template/lib/blocks/inlineScriptNonce.ts +20 -20
  206. package/templates/nextblock-template/lib/cms/contact-reminder.ts +64 -64
  207. package/templates/nextblock-template/lib/cms/payments-reminder.test.ts +135 -0
  208. package/templates/nextblock-template/lib/cms/payments-reminder.ts +30 -23
  209. package/templates/nextblock-template/lib/cms/unread-messages.ts +42 -42
  210. package/templates/nextblock-template/lib/commerce/seller-contact.ts +162 -162
  211. package/templates/nextblock-template/lib/config/email-settings.ts +323 -323
  212. package/templates/nextblock-template/lib/config/email-tls.test.ts +57 -57
  213. package/templates/nextblock-template/lib/cortex-ai/alt-text-request.ts +86 -86
  214. package/templates/nextblock-template/lib/cortex-ai/sandbox-headers.ts +60 -60
  215. package/templates/nextblock-template/lib/email/placeholder-address.test.ts +59 -59
  216. package/templates/nextblock-template/lib/email/placeholder-address.ts +39 -39
  217. package/templates/nextblock-template/lib/messages/thread-reference.test.ts +70 -70
  218. package/templates/nextblock-template/lib/messages/thread-token.test.ts +93 -93
  219. package/templates/nextblock-template/lib/messages/thread-token.ts +157 -157
  220. package/templates/nextblock-template/lib/messages/threads.ts +579 -579
  221. package/templates/nextblock-template/lib/posts/readTime.ts +60 -60
  222. package/templates/nextblock-template/lib/publishing/viewUrl.ts +26 -26
  223. package/templates/nextblock-template/lib/search/types.ts +27 -27
  224. package/templates/nextblock-template/lib/seo/alt-text-write-back.test.ts +154 -154
  225. package/templates/nextblock-template/lib/seo/alt-text-write-back.ts +109 -109
  226. package/templates/nextblock-template/lib/seo/block-content.ts +123 -123
  227. package/templates/nextblock-template/lib/seo/fix-prompts.test.ts +242 -242
  228. package/templates/nextblock-template/lib/seo/fix-prompts.ts +204 -204
  229. package/templates/nextblock-template/lib/seo/page-audit-context.tsx +157 -140
  230. package/templates/nextblock-template/lib/seo/page-document.test.ts +384 -350
  231. package/templates/nextblock-template/lib/seo/page-document.ts +463 -412
  232. package/templates/nextblock-template/lib/seo/redirect-store.test.ts +479 -479
  233. package/templates/nextblock-template/lib/seo/redirect-store.ts +466 -466
  234. package/templates/nextblock-template/lib/seo/robots-settings-signature.test.ts +102 -102
  235. package/templates/nextblock-template/lib/seo/robots-settings-signature.ts +41 -41
  236. package/templates/nextblock-template/lib/seo/robots-txt.test.ts +370 -370
  237. package/templates/nextblock-template/lib/seo/robots-txt.ts +510 -510
  238. package/templates/nextblock-template/lib/setup/migrations-bundle.ts +37 -22
  239. package/templates/nextblock-template/lib/site-scripts/revisions.ts +71 -71
  240. package/templates/nextblock-template/lib/site-scripts/types.ts +46 -46
  241. package/templates/nextblock-template/lib/site-url.test.ts +89 -89
  242. package/templates/nextblock-template/lib/site-url.ts +102 -102
  243. package/templates/nextblock-template/lib/themes/buildThemeCss.ts +124 -124
  244. package/templates/nextblock-template/lib/themes/tokenColor.ts +31 -31
  245. package/templates/nextblock-template/lib/themes/tokens.ts +143 -143
  246. package/templates/nextblock-template/lib/visual-editing/draft-content.test.ts +105 -105
  247. package/templates/nextblock-template/lib/visual-editing/draft-route.test.ts +42 -42
  248. package/templates/nextblock-template/lib/visual-editing/edit-info.test.ts +143 -143
  249. package/templates/nextblock-template/lib/visual-editing/edit-info.ts +94 -94
  250. package/templates/nextblock-template/lib/visual-editing/product-drafts.test.ts +81 -81
  251. package/templates/nextblock-template/lib/zod-config.ts +5 -5
  252. package/templates/nextblock-template/next-env.d.ts +1 -2
  253. package/templates/nextblock-template/package.json +1 -1
  254. package/templates/nextblock-template/postcss.config.js +6 -6
  255. package/templates/nextblock-template/scripts/backup.js +115 -115
  256. package/templates/nextblock-template/scripts/restore.js +385 -385
  257. package/templates/nextblock-template/scripts/validate-editor-block-schema.ts +112 -112
  258. package/templates/nextblock-template/tailwind.config.js +25 -25
  259. package/templates/nextblock-template/tools/build-migrate.mjs +102 -102
  260. package/templates/nextblock-template/tools/configure-supabase-auth.js +282 -282
  261. package/templates/nextblock-template/tools/deploy-supabase.js +159 -159
  262. package/templates/nextblock-template/tools/lib/migrate-core.mjs +569 -569
  263. package/templates/nextblock-template/tools/update.mjs +1303 -1303
  264. package/tsconfig.base.json +3 -3
@@ -1,44 +1,44 @@
1
- "use client";
2
-
3
- import { createContext, useContext, useMemo, type ReactNode } from "react";
4
-
5
- /** The switcher-facing shape of a row in `site_themes`. */
6
- export interface ThemeCatalogEntry {
7
- slug: string;
8
- name: string;
9
- /** lucide-react icon name. */
10
- icon: string;
11
- colorScheme: "light" | "dark";
12
- }
13
-
14
- /**
15
- * Themes are read once on the server in app/layout.tsx and handed to the client
16
- * through this context, so the switcher never fetches and never hardcodes a
17
- * list. Falls back to the palette shipped in libs/ui/src/styles/theme.css when
18
- * the table is empty or unreachable.
19
- */
20
- export const FALLBACK_THEME_CATALOG: ThemeCatalogEntry[] = [
21
- { slug: "light", name: "Light", icon: "Sun", colorScheme: "light" },
22
- { slug: "dark", name: "Dark", icon: "Moon", colorScheme: "dark" },
23
- { slug: "vibrant", name: "Vibrant", icon: "Zap", colorScheme: "dark" },
24
- ];
25
-
26
- const ThemeCatalogContext = createContext<ThemeCatalogEntry[]>(FALLBACK_THEME_CATALOG);
27
-
28
- export function ThemeCatalogProvider({
29
- themes,
30
- children,
31
- }: {
32
- themes?: ThemeCatalogEntry[];
33
- children: ReactNode;
34
- }) {
35
- const value = useMemo(
36
- () => (Array.isArray(themes) && themes.length > 0 ? themes : FALLBACK_THEME_CATALOG),
37
- [themes],
38
- );
39
- return <ThemeCatalogContext.Provider value={value}>{children}</ThemeCatalogContext.Provider>;
40
- }
41
-
42
- export function useThemeCatalog(): ThemeCatalogEntry[] {
43
- return useContext(ThemeCatalogContext);
44
- }
1
+ "use client";
2
+
3
+ import { createContext, useContext, useMemo, type ReactNode } from "react";
4
+
5
+ /** The switcher-facing shape of a row in `site_themes`. */
6
+ export interface ThemeCatalogEntry {
7
+ slug: string;
8
+ name: string;
9
+ /** lucide-react icon name. */
10
+ icon: string;
11
+ colorScheme: "light" | "dark";
12
+ }
13
+
14
+ /**
15
+ * Themes are read once on the server in app/layout.tsx and handed to the client
16
+ * through this context, so the switcher never fetches and never hardcodes a
17
+ * list. Falls back to the palette shipped in libs/ui/src/styles/theme.css when
18
+ * the table is empty or unreachable.
19
+ */
20
+ export const FALLBACK_THEME_CATALOG: ThemeCatalogEntry[] = [
21
+ { slug: "light", name: "Light", icon: "Sun", colorScheme: "light" },
22
+ { slug: "dark", name: "Dark", icon: "Moon", colorScheme: "dark" },
23
+ { slug: "vibrant", name: "Vibrant", icon: "Zap", colorScheme: "dark" },
24
+ ];
25
+
26
+ const ThemeCatalogContext = createContext<ThemeCatalogEntry[]>(FALLBACK_THEME_CATALOG);
27
+
28
+ export function ThemeCatalogProvider({
29
+ themes,
30
+ children,
31
+ }: {
32
+ themes?: ThemeCatalogEntry[];
33
+ children: ReactNode;
34
+ }) {
35
+ const value = useMemo(
36
+ () => (Array.isArray(themes) && themes.length > 0 ? themes : FALLBACK_THEME_CATALOG),
37
+ [themes],
38
+ );
39
+ return <ThemeCatalogContext.Provider value={value}>{children}</ThemeCatalogContext.Provider>;
40
+ }
41
+
42
+ export function useThemeCatalog(): ThemeCatalogEntry[] {
43
+ return useContext(ThemeCatalogContext);
44
+ }
@@ -1,94 +1,94 @@
1
- # 01 Project Overview
2
-
3
- ## What NextBlock Is
4
-
5
- NextBlock is an Nx monorepo centered on a Next.js 16 application
6
- (`apps/nextblock`) backed by Supabase. The public site, authenticated CMS,
7
- shared editor, shared database helpers, shared UI primitives, and CLI scaffold
8
- all live in one workspace.
9
-
10
- The repository currently contains:
11
-
12
- - `apps/nextblock`: the canonical application. This is the runtime source of
13
- truth for the public site, CMS, checkout routes, cron routes, and auth
14
- callback behavior.
15
- - `apps/create-nextblock`: the CLI that copies a sanitized template from the
16
- source app and rewrites it for package-based distribution.
17
- - `libs/db`: Supabase clients, package activation checks, generated database
18
- types, and the migration tree under `libs/db/src/supabase/migrations`.
19
- - `libs/editor`: the reusable Tiptap-based editor package used by the CMS and
20
- by scaffolded projects.
21
- - `libs/ecommerce`: the premium commerce package that provides storefront UI,
22
- checkout providers, order handling, shipping, tax, currency, and CMS pages.
23
- - `libs/sdk`: the block authoring contract used for typed extensibility.
24
- - `libs/ui` and `libs/utils`: shared UI components, styles, and helper
25
- utilities consumed throughout the workspace.
26
-
27
- ## Runtime Model
28
-
29
- The `apps/nextblock/app` tree is split into a few clear surfaces:
30
-
31
- - Public routes: `app/[slug]`, `app/article/[slug]`, `app/product/*`,
32
- `app/cart`, `app/checkout`, and the shared public `app/layout.tsx`.
33
- - Auth routes: `app/(auth-pages)/*` plus `app/auth/callback/route.ts`.
34
- - CMS routes: `app/cms/*`.
35
- - Operational routes: `app/api/checkout/route.ts`,
36
- `app/api/webhooks/*`, `app/api/cron/*`, `robots.txt`, and `sitemap.xml`.
37
-
38
- The public root layout loads shared UI and editor styles, resolves cached
39
- layout data from Supabase, injects the storefront cart drawer, and reads the
40
- storefront currency cookie. The CMS layout checks whether the ecommerce package
41
- is active so the client-side CMS shell can show or hide store navigation.
42
-
43
- ## CMS and Public Site Split
44
-
45
- The public application and CMS are not separate projects. They share the same
46
- Next.js app and database, but expose different route groups and different
47
- authorization requirements:
48
-
49
- - Public content is driven by published pages, posts, navigation, products, and
50
- translations stored in Supabase.
51
- - CMS routes are guarded in the client layout and expect an authenticated user
52
- whose profile role is `ADMIN` or `WRITER`.
53
- - Commerce CMS routes such as products, orders, shipping, taxes, and payments
54
- are only meaningful when the ecommerce package is active.
55
-
56
- ## Package Activation Gating
57
-
58
- Premium functionality is gated through `package_activations` and
59
- `verifyPackageOnline()` in `libs/db/src/lib/package-validation.ts`.
60
-
61
- Today that gate is used directly in the app for things like:
62
-
63
- - CMS ecommerce navigation visibility.
64
- - The checkout API.
65
- - Premium route wrappers and CLI module activation flows.
66
-
67
- If a package gate and the actual route behavior disagree, the route file wins.
68
-
69
- ## Nx Workspace Shape
70
-
71
- Nx is used for project graph management, builds, linting, Vite-based library
72
- output, and Next.js app targets. A few practical notes matter when navigating
73
- the repo:
74
-
75
- - `nextblock` is the main application target.
76
- - Public libraries such as `db`, `editor`, `sdk`, `ui`, and `utils` are normal
77
- Nx projects.
78
- - `ecommerce` is an Nx library tagged `scope:premium`.
79
- - The scaffold template under
80
- `apps/create-nextblock/templates/nextblock-template` is intentionally copied
81
- output, not a normal Nx project.
82
-
83
- ## Where to Start
84
-
85
- - For overall architecture: read [04-DATABASE-AND-AUTH.md](./04-DATABASE-AND-AUTH.md)
86
- after this file.
87
- - For day-to-day setup and commands: read
88
- [05-DEVELOPER-GUIDE.md](./05-DEVELOPER-GUIDE.md).
89
- - For CLI behavior and template sync: read
90
- [06-CLI-AND-SCAFFOLDING.md](./06-CLI-AND-SCAFFOLDING.md).
91
- - For editor and block work: read
92
- [03-CMS-AND-EDITOR.md](./03-CMS-AND-EDITOR.md).
93
- - For commerce work: read
94
- [02-ECOMMERCE-CAPABILITIES.md](./02-ECOMMERCE-CAPABILITIES.md).
1
+ # 01 Project Overview
2
+
3
+ ## What NextBlock Is
4
+
5
+ NextBlock is an Nx monorepo centered on a Next.js 16 application
6
+ (`apps/nextblock`) backed by Supabase. The public site, authenticated CMS,
7
+ shared editor, shared database helpers, shared UI primitives, and CLI scaffold
8
+ all live in one workspace.
9
+
10
+ The repository currently contains:
11
+
12
+ - `apps/nextblock`: the canonical application. This is the runtime source of
13
+ truth for the public site, CMS, checkout routes, cron routes, and auth
14
+ callback behavior.
15
+ - `apps/create-nextblock`: the CLI that copies a sanitized template from the
16
+ source app and rewrites it for package-based distribution.
17
+ - `libs/db`: Supabase clients, package activation checks, generated database
18
+ types, and the migration tree under `libs/db/src/supabase/migrations`.
19
+ - `libs/editor`: the reusable Tiptap-based editor package used by the CMS and
20
+ by scaffolded projects.
21
+ - `libs/ecommerce`: the premium commerce package that provides storefront UI,
22
+ checkout providers, order handling, shipping, tax, currency, and CMS pages.
23
+ - `libs/sdk`: the block authoring contract used for typed extensibility.
24
+ - `libs/ui` and `libs/utils`: shared UI components, styles, and helper
25
+ utilities consumed throughout the workspace.
26
+
27
+ ## Runtime Model
28
+
29
+ The `apps/nextblock/app` tree is split into a few clear surfaces:
30
+
31
+ - Public routes: `app/[slug]`, `app/article/[slug]`, `app/product/*`,
32
+ `app/cart`, `app/checkout`, and the shared public `app/layout.tsx`.
33
+ - Auth routes: `app/(auth-pages)/*` plus `app/auth/callback/route.ts`.
34
+ - CMS routes: `app/cms/*`.
35
+ - Operational routes: `app/api/checkout/route.ts`,
36
+ `app/api/webhooks/*`, `app/api/cron/*`, `robots.txt`, and `sitemap.xml`.
37
+
38
+ The public root layout loads shared UI and editor styles, resolves cached
39
+ layout data from Supabase, injects the storefront cart drawer, and reads the
40
+ storefront currency cookie. The CMS layout checks whether the ecommerce package
41
+ is active so the client-side CMS shell can show or hide store navigation.
42
+
43
+ ## CMS and Public Site Split
44
+
45
+ The public application and CMS are not separate projects. They share the same
46
+ Next.js app and database, but expose different route groups and different
47
+ authorization requirements:
48
+
49
+ - Public content is driven by published pages, posts, navigation, products, and
50
+ translations stored in Supabase.
51
+ - CMS routes are guarded in the client layout and expect an authenticated user
52
+ whose profile role is `ADMIN` or `WRITER`.
53
+ - Commerce CMS routes such as products, orders, shipping, taxes, and payments
54
+ are only meaningful when the ecommerce package is active.
55
+
56
+ ## Package Activation Gating
57
+
58
+ Premium functionality is gated through `package_activations` and
59
+ `verifyPackageOnline()` in `libs/db/src/lib/package-validation.ts`.
60
+
61
+ Today that gate is used directly in the app for things like:
62
+
63
+ - CMS ecommerce navigation visibility.
64
+ - The checkout API.
65
+ - Premium route wrappers and CLI module activation flows.
66
+
67
+ If a package gate and the actual route behavior disagree, the route file wins.
68
+
69
+ ## Nx Workspace Shape
70
+
71
+ Nx is used for project graph management, builds, linting, Vite-based library
72
+ output, and Next.js app targets. A few practical notes matter when navigating
73
+ the repo:
74
+
75
+ - `nextblock` is the main application target.
76
+ - Public libraries such as `db`, `editor`, `sdk`, `ui`, and `utils` are normal
77
+ Nx projects.
78
+ - `ecommerce` is an Nx library tagged `scope:premium`.
79
+ - The scaffold template under
80
+ `apps/create-nextblock/templates/nextblock-template` is intentionally copied
81
+ output, not a normal Nx project.
82
+
83
+ ## Where to Start
84
+
85
+ - For overall architecture: read [04-DATABASE-AND-AUTH.md](./04-DATABASE-AND-AUTH.md)
86
+ after this file.
87
+ - For day-to-day setup and commands: read
88
+ [05-DEVELOPER-GUIDE.md](./05-DEVELOPER-GUIDE.md).
89
+ - For CLI behavior and template sync: read
90
+ [06-CLI-AND-SCAFFOLDING.md](./06-CLI-AND-SCAFFOLDING.md).
91
+ - For editor and block work: read
92
+ [03-CMS-AND-EDITOR.md](./03-CMS-AND-EDITOR.md).
93
+ - For commerce work: read
94
+ [02-ECOMMERCE-CAPABILITIES.md](./02-ECOMMERCE-CAPABILITIES.md).
@@ -200,80 +200,80 @@ contract lives in `libs/sdk` and is documented in
200
200
 
201
201
  If you are changing how blocks work inside the CMS, start here. If you are
202
202
  designing a reusable third-party block contract, start with the SDK doc.
203
-
204
- ## Themes and Colour
205
-
206
- ### Editable site themes
207
-
208
- Themes are rows in `site_themes`, edited at **/cms/settings/global-css**. An
209
- ADMIN can recolour any theme, create new ones, duplicate, reorder, hide, set the
210
- site default, and delete non-system themes.
211
-
212
- The pipeline is:
213
-
214
- 1. `app/layout.tsx` reads the table through a cached `getCachedSiteThemes()`
215
- (tag `public-layout-site-themes`).
216
- 2. `lib/themes/buildThemeCss.ts` renders each row to a `:root.<slug> { ... }`
217
- rule, injected as a `<style id="nb-theme-tokens">` in `<head>` — before the
218
- Global CSS box, so custom CSS can still override a theme.
219
- 3. `app/providers.tsx` feeds the slug list and default to `next-themes`, and
220
- `context/ThemeCatalogContext.tsx` carries names + icons to the switcher.
221
-
222
- `libs/ui/src/styles/theme.css` remains as the fallback palette for standalone
223
- consumers of the published `@nextblock-cms/ui` package. Generated rules use
224
- `:root.<slug>` (specificity 0,2,0) so they always beat that file's `.dark` /
225
- `.vibrant` rules (0,1,0) regardless of stylesheet order.
226
-
227
- ### Token storage
228
-
229
- Colour tokens are stored as **bare HSL triplets** (`"222 47% 11%"`), not hex,
230
- because `libs/ui/tailwind.config.js` composes them as `hsl(var(--primary))` and
231
- appends alpha as `hsl(var(--primary) / 0.5)` — only a bare triplet supports
232
- that. `lib/themes/tokenColor.ts` converts to and from the hex the colour picker
233
- speaks. The allowed token list lives in `lib/themes/tokens.ts`; anything not on
234
- it is dropped on save, and values are shape-checked, because the result is
235
- interpolated into a `<style>` tag.
236
-
237
- Per-theme `extra_css` is emitted **nested inside** the theme rule, so authors
238
- write `& h1 { ... }` and scoping is automatic. `sanitizeExtraCss()` strips `<`
239
- and unbalanced `}` so it cannot escape the rule or close the style element.
240
-
241
- ### Known limitation: `dark:` utilities under custom themes
242
-
243
- Tailwind's dark variant compiles to `.dark`, and `darkMode: ['class']` is fixed
244
- at build time. A custom theme with `color_scheme: 'dark'` recolours every token
245
- and sets CSS `color-scheme`, but does **not** activate `dark:` utilities — the
246
- same behaviour the shipped `.vibrant` theme has always had.
247
-
248
- It cannot be fixed by mapping the theme to two classes: `next-themes` applies
249
- its value with a single `classList.add(value)`, and `DOMTokenList.add` throws
250
- `InvalidCharacterError` on a string containing a space. Wiring `dark:` to a data
251
- attribute would require a pre-hydration script mirroring next-themes' own.
252
-
253
- Verify the database → CSS path without booting the app:
254
-
255
- ```bash
256
- npm run verify:site-themes
257
- ```
258
-
259
- ### Block text colour
260
-
261
- `apps/nextblock/lib/blocks/blockColors.ts` is the single source of truth for
262
- block text colour, shared by `HeadingBlockRenderer`, `EditableBlock` and
263
- `ColumnEditor` so the CMS preview cannot drift from the live page.
264
-
265
- A stored value is either a **theme token** keyword (`"primary"` — follows the
266
- theme) or a **literal CSS colour** (`"#FF8800"` — fixed). Tokens render as a
267
- static Tailwind class; literals render as an inline `style`. `resolveTextColor()`
268
- returns `{ className?, style? }` and falls back to `{}` for anything it does not
269
- recognise, so a hand-edited value degrades to the inherited colour instead of
270
- emitting a bogus class.
271
-
272
- Class names here are written as **complete literals**. Tailwind v4 ignores the
273
- `safelist` key in the legacy JS config — `libs/ui/tailwind.config.js` still
274
- carries one, but v4 never reads it, so a class exists only if the scanner finds
275
- the whole string in a source file.
276
-
277
- The editor control is `ColorField` from `libs/ui`, which offers the theme tokens
278
- and a custom picker (hex, alpha, screen eyedropper, recent colours) with a live
279
- WCAG contrast badge measured against the section background.
203
+
204
+ ## Themes and Colour
205
+
206
+ ### Editable site themes
207
+
208
+ Themes are rows in `site_themes`, edited at **/cms/settings/global-css**. An
209
+ ADMIN can recolour any theme, create new ones, duplicate, reorder, hide, set the
210
+ site default, and delete non-system themes.
211
+
212
+ The pipeline is:
213
+
214
+ 1. `app/layout.tsx` reads the table through a cached `getCachedSiteThemes()`
215
+ (tag `public-layout-site-themes`).
216
+ 2. `lib/themes/buildThemeCss.ts` renders each row to a `:root.<slug> { ... }`
217
+ rule, injected as a `<style id="nb-theme-tokens">` in `<head>` — before the
218
+ Global CSS box, so custom CSS can still override a theme.
219
+ 3. `app/providers.tsx` feeds the slug list and default to `next-themes`, and
220
+ `context/ThemeCatalogContext.tsx` carries names + icons to the switcher.
221
+
222
+ `libs/ui/src/styles/theme.css` remains as the fallback palette for standalone
223
+ consumers of the published `@nextblock-cms/ui` package. Generated rules use
224
+ `:root.<slug>` (specificity 0,2,0) so they always beat that file's `.dark` /
225
+ `.vibrant` rules (0,1,0) regardless of stylesheet order.
226
+
227
+ ### Token storage
228
+
229
+ Colour tokens are stored as **bare HSL triplets** (`"222 47% 11%"`), not hex,
230
+ because `libs/ui/tailwind.config.js` composes them as `hsl(var(--primary))` and
231
+ appends alpha as `hsl(var(--primary) / 0.5)` — only a bare triplet supports
232
+ that. `lib/themes/tokenColor.ts` converts to and from the hex the colour picker
233
+ speaks. The allowed token list lives in `lib/themes/tokens.ts`; anything not on
234
+ it is dropped on save, and values are shape-checked, because the result is
235
+ interpolated into a `<style>` tag.
236
+
237
+ Per-theme `extra_css` is emitted **nested inside** the theme rule, so authors
238
+ write `& h1 { ... }` and scoping is automatic. `sanitizeExtraCss()` strips `<`
239
+ and unbalanced `}` so it cannot escape the rule or close the style element.
240
+
241
+ ### Known limitation: `dark:` utilities under custom themes
242
+
243
+ Tailwind's dark variant compiles to `.dark`, and `darkMode: ['class']` is fixed
244
+ at build time. A custom theme with `color_scheme: 'dark'` recolours every token
245
+ and sets CSS `color-scheme`, but does **not** activate `dark:` utilities — the
246
+ same behaviour the shipped `.vibrant` theme has always had.
247
+
248
+ It cannot be fixed by mapping the theme to two classes: `next-themes` applies
249
+ its value with a single `classList.add(value)`, and `DOMTokenList.add` throws
250
+ `InvalidCharacterError` on a string containing a space. Wiring `dark:` to a data
251
+ attribute would require a pre-hydration script mirroring next-themes' own.
252
+
253
+ Verify the database → CSS path without booting the app:
254
+
255
+ ```bash
256
+ npm run verify:site-themes
257
+ ```
258
+
259
+ ### Block text colour
260
+
261
+ `apps/nextblock/lib/blocks/blockColors.ts` is the single source of truth for
262
+ block text colour, shared by `HeadingBlockRenderer`, `EditableBlock` and
263
+ `ColumnEditor` so the CMS preview cannot drift from the live page.
264
+
265
+ A stored value is either a **theme token** keyword (`"primary"` — follows the
266
+ theme) or a **literal CSS colour** (`"#FF8800"` — fixed). Tokens render as a
267
+ static Tailwind class; literals render as an inline `style`. `resolveTextColor()`
268
+ returns `{ className?, style? }` and falls back to `{}` for anything it does not
269
+ recognise, so a hand-edited value degrades to the inherited colour instead of
270
+ emitting a bogus class.
271
+
272
+ Class names here are written as **complete literals**. Tailwind v4 ignores the
273
+ `safelist` key in the legacy JS config — `libs/ui/tailwind.config.js` still
274
+ carries one, but v4 never reads it, so a class exists only if the scanner finds
275
+ the whole string in a source file.
276
+
277
+ The editor control is `ColorField` from `libs/ui`, which offers the theme tokens
278
+ and a custom picker (hex, alpha, screen eyedropper, recent colours) with a live
279
+ WCAG contrast badge measured against the section background.