create-nextblock 0.15.10 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) 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 -0
  26. package/templates/nextblock-template/app/api/ai/seo/metadata/route.ts +186 -0
  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/sandboxResetSql.ts +3092 -2900
  30. package/templates/nextblock-template/app/api/mcp/route.ts +415 -415
  31. package/templates/nextblock-template/app/api/media/record/route.ts +160 -160
  32. package/templates/nextblock-template/app/api/search/route.ts +43 -43
  33. package/templates/nextblock-template/app/api/view/route.ts +114 -114
  34. package/templates/nextblock-template/app/api/visual-editing/block-draft/route.ts +47 -47
  35. package/templates/nextblock-template/app/api/visual-editing/product-draft/route.ts +47 -47
  36. package/templates/nextblock-template/app/auth/callback/route.ts +31 -31
  37. package/templates/nextblock-template/app/cart/page.tsx +7 -7
  38. package/templates/nextblock-template/app/checkout/UcpCartHydrator.tsx +20 -20
  39. package/templates/nextblock-template/app/checkout/page.tsx +57 -57
  40. package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +558 -552
  41. package/templates/nextblock-template/app/cms/blocks/components/BlockEditorArea.tsx +27 -0
  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 +180 -3
  46. package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +171 -6
  47. package/templates/nextblock-template/app/cms/components/ContactReminderBanner.tsx +75 -75
  48. package/templates/nextblock-template/app/cms/components/CortexAiActiveContext.tsx +23 -23
  49. package/templates/nextblock-template/app/cms/components/CortexAiPageContext.tsx +58 -58
  50. package/templates/nextblock-template/app/cms/components/FeatureImageField.tsx +12 -3
  51. package/templates/nextblock-template/app/cms/components/FeedbackModal.tsx +36 -36
  52. package/templates/nextblock-template/app/cms/components/PaymentsReminderBanner.tsx +58 -58
  53. package/templates/nextblock-template/app/cms/components/VisibilityBadge.tsx +62 -62
  54. package/templates/nextblock-template/app/cms/components/VisibilityControl.tsx +542 -542
  55. package/templates/nextblock-template/app/cms/coupons/[id]/edit/page.tsx +16 -16
  56. package/templates/nextblock-template/app/cms/coupons/page.tsx +16 -16
  57. package/templates/nextblock-template/app/cms/dashboard/actions.ts +228 -228
  58. package/templates/nextblock-template/app/cms/dashboard/components/DashboardComponents.tsx +200 -200
  59. package/templates/nextblock-template/app/cms/inquiries/actions.ts +66 -66
  60. package/templates/nextblock-template/app/cms/inquiries/page.tsx +12 -12
  61. package/templates/nextblock-template/app/cms/interactions/page.tsx +12 -12
  62. package/templates/nextblock-template/app/cms/layout.tsx +101 -101
  63. package/templates/nextblock-template/app/cms/media/components/FolderNavigator.tsx +273 -273
  64. package/templates/nextblock-template/app/cms/media/components/FolderTree.tsx +122 -122
  65. package/templates/nextblock-template/app/cms/media/components/MediaEditForm.tsx +177 -2
  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/[id]/edit/EditPageClient.tsx +28 -0
  74. package/templates/nextblock-template/app/cms/pages/components/PageForm.tsx +248 -5
  75. package/templates/nextblock-template/app/cms/posts/[id]/edit/page.tsx +33 -0
  76. package/templates/nextblock-template/app/cms/posts/components/PostForm.tsx +240 -5
  77. package/templates/nextblock-template/app/cms/products/[id]/edit/page.tsx +370 -370
  78. package/templates/nextblock-template/app/cms/products/attributes/page.tsx +12 -12
  79. package/templates/nextblock-template/app/cms/products/inventory/page.tsx +13 -13
  80. package/templates/nextblock-template/app/cms/products/productFormData.ts +133 -133
  81. package/templates/nextblock-template/app/cms/products/settings/page.tsx +5 -5
  82. package/templates/nextblock-template/app/cms/revisions/actions.ts +332 -332
  83. package/templates/nextblock-template/app/cms/revisions/service.test.ts +498 -498
  84. package/templates/nextblock-template/app/cms/revisions/service.ts +569 -569
  85. package/templates/nextblock-template/app/cms/revisions/utils.ts +304 -304
  86. package/templates/nextblock-template/app/cms/settings/cortex-ai/CortexAiSettingsClient.tsx +948 -948
  87. package/templates/nextblock-template/app/cms/settings/cortex-ai/McpServerSettingsCard.tsx +628 -628
  88. package/templates/nextblock-template/app/cms/settings/cortex-ai/mcp-actions.ts +230 -230
  89. package/templates/nextblock-template/app/cms/settings/cortex-ai/require-admin.ts +34 -34
  90. package/templates/nextblock-template/app/cms/settings/currencies/actions.ts +331 -331
  91. package/templates/nextblock-template/app/cms/settings/currencies/page.tsx +494 -494
  92. package/templates/nextblock-template/app/cms/settings/email/components/EmailForm.tsx +227 -227
  93. package/templates/nextblock-template/app/cms/settings/extra-translations/ExtraTranslationsWorkspace.tsx +767 -767
  94. package/templates/nextblock-template/app/cms/settings/extra-translations/actions.ts +276 -276
  95. package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +93 -93
  96. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeEditor.tsx +382 -382
  97. package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeManager.tsx +267 -267
  98. package/templates/nextblock-template/app/cms/settings/global-css/page.tsx +40 -40
  99. package/templates/nextblock-template/app/cms/settings/global-css/theme-actions.ts +259 -259
  100. package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +7 -7
  101. package/templates/nextblock-template/app/cms/settings/logos/components/BrandingSettingsForm.tsx +339 -339
  102. package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +8 -8
  103. package/templates/nextblock-template/app/cms/settings/seo/RedirectsCard.tsx +514 -0
  104. package/templates/nextblock-template/app/cms/settings/seo/RobotsCard.tsx +529 -0
  105. package/templates/nextblock-template/app/cms/settings/seo/SeoSettingsClient.tsx +57 -0
  106. package/templates/nextblock-template/app/cms/settings/seo/actions.ts +448 -0
  107. package/templates/nextblock-template/app/cms/settings/seo/mappers.ts +93 -0
  108. package/templates/nextblock-template/app/cms/settings/seo/page.tsx +46 -0
  109. package/templates/nextblock-template/app/cms/settings/seo/require-admin.ts +47 -0
  110. package/templates/nextblock-template/app/cms/settings/site-scripts/page.tsx +51 -51
  111. package/templates/nextblock-template/app/cms/settings/taxes/page.tsx +21 -21
  112. package/templates/nextblock-template/app/cms/shipping/page.tsx +20 -20
  113. package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +12 -12
  114. package/templates/nextblock-template/app/layout.tsx +671 -671
  115. package/templates/nextblock-template/app/lib/seo.ts +319 -319
  116. package/templates/nextblock-template/app/lib/ucp/protocol.ts +190 -190
  117. package/templates/nextblock-template/app/lib/ucp/server.test.ts +56 -56
  118. package/templates/nextblock-template/app/product/[slug]/page.tsx +502 -502
  119. package/templates/nextblock-template/app/profile/ProfilePageHeader.tsx +16 -16
  120. package/templates/nextblock-template/app/profile/ProfilePageMissingState.tsx +9 -9
  121. package/templates/nextblock-template/app/profile/account-links.ts +22 -22
  122. package/templates/nextblock-template/app/profile/orders/CustomerOrdersPageClient.tsx +124 -124
  123. package/templates/nextblock-template/app/profile/orders/page.tsx +19 -19
  124. package/templates/nextblock-template/app/profile/password/PasswordSettingsPageClient.tsx +128 -128
  125. package/templates/nextblock-template/app/profile/password/actions.ts +59 -59
  126. package/templates/nextblock-template/app/profile/password/page.tsx +27 -27
  127. package/templates/nextblock-template/app/providers.tsx +96 -96
  128. package/templates/nextblock-template/app/robots.ts +123 -0
  129. package/templates/nextblock-template/app/sitemap.ts +1 -1
  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 -0
  181. package/templates/nextblock-template/components/seo/PageSeoAuditSection.tsx +244 -0
  182. package/templates/nextblock-template/components/seo/SeoAuditPanel.tsx +749 -0
  183. package/templates/nextblock-template/components/seo/SeoIssueList.tsx +195 -0
  184. package/templates/nextblock-template/components/seo/SeoScoreDial.tsx +144 -0
  185. package/templates/nextblock-template/components/seo/SocialPreview.tsx +243 -0
  186. package/templates/nextblock-template/components/seo/SocialPreviewDialog.tsx +110 -0
  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 -0
  214. package/templates/nextblock-template/lib/cortex-ai/sandbox-headers.ts +60 -0
  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 -0
  225. package/templates/nextblock-template/lib/seo/alt-text-write-back.ts +109 -0
  226. package/templates/nextblock-template/lib/seo/block-content.ts +123 -0
  227. package/templates/nextblock-template/lib/seo/fix-prompts.test.ts +242 -0
  228. package/templates/nextblock-template/lib/seo/fix-prompts.ts +204 -0
  229. package/templates/nextblock-template/lib/seo/page-audit-context.tsx +140 -0
  230. package/templates/nextblock-template/lib/seo/page-document.test.ts +350 -0
  231. package/templates/nextblock-template/lib/seo/page-document.ts +412 -0
  232. package/templates/nextblock-template/lib/seo/redirect-store.test.ts +479 -0
  233. package/templates/nextblock-template/lib/seo/redirect-store.ts +466 -0
  234. package/templates/nextblock-template/lib/seo/robots-settings-signature.test.ts +102 -0
  235. package/templates/nextblock-template/lib/seo/robots-settings-signature.ts +41 -0
  236. package/templates/nextblock-template/lib/seo/robots-txt.test.ts +370 -0
  237. package/templates/nextblock-template/lib/seo/robots-txt.ts +510 -0
  238. package/templates/nextblock-template/lib/setup/migrations-bundle.ts +177 -167
  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 +0 -1
  253. package/templates/nextblock-template/package.json +1 -1
  254. package/templates/nextblock-template/postcss.config.js +6 -6
  255. package/templates/nextblock-template/proxy.ts +240 -20
  256. package/templates/nextblock-template/scripts/backup.js +115 -115
  257. package/templates/nextblock-template/scripts/restore.js +385 -385
  258. package/templates/nextblock-template/scripts/validate-editor-block-schema.ts +112 -112
  259. package/templates/nextblock-template/tailwind.config.js +25 -25
  260. package/templates/nextblock-template/tools/build-migrate.mjs +102 -102
  261. package/templates/nextblock-template/tools/configure-supabase-auth.js +282 -282
  262. package/templates/nextblock-template/tools/deploy-supabase.js +159 -159
  263. package/templates/nextblock-template/tools/lib/migrate-core.mjs +569 -569
  264. package/templates/nextblock-template/tools/update.mjs +1303 -1303
  265. package/tsconfig.base.json +3 -3
  266. package/templates/nextblock-template/app/robots.txt/route.ts +0 -32
@@ -1,58 +1,58 @@
1
- "use client";
2
-
3
- import React, { createContext, useContext, useEffect, useMemo, useState } from "react";
4
-
5
- export type CortexAiContentType = "page" | "post" | "product";
6
-
7
- export type CortexAiPageContext = {
8
- contentType: CortexAiContentType;
9
- currentEditor?: {
10
- blockId?: number | string | null;
11
- blockType?: string | null;
12
- field?: string | null;
13
- };
14
- entityId: number | string;
15
- languageId?: number | null;
16
- slug?: string | null;
17
- title?: string | null;
18
- translationGroupId?: string | null;
19
- };
20
-
21
- type CortexAiPageContextValue = {
22
- pageContext: CortexAiPageContext | null;
23
- setPageContext: (context: CortexAiPageContext | null) => void;
24
- };
25
-
26
- const CortexAiPageContextStore = createContext<CortexAiPageContextValue | null>(null);
27
-
28
- export function CortexAiPageContextProvider({ children }: { children: React.ReactNode }) {
29
- const [pageContext, setPageContext] = useState<CortexAiPageContext | null>(null);
30
- const value = useMemo(() => ({ pageContext, setPageContext }), [pageContext]);
31
-
32
- return (
33
- <CortexAiPageContextStore.Provider value={value}>
34
- {children}
35
- </CortexAiPageContextStore.Provider>
36
- );
37
- }
38
-
39
- export function useCortexAiPageContext() {
40
- return useContext(CortexAiPageContextStore);
41
- }
42
-
43
- export function CortexAiPageContextRegistrar({
44
- context,
45
- }: {
46
- context: CortexAiPageContext;
47
- }) {
48
- const store = useCortexAiPageContext();
49
- const setPageContext = store?.setPageContext;
50
- const serializedContext = JSON.stringify(context);
51
-
52
- useEffect(() => {
53
- setPageContext?.(context);
54
- return () => setPageContext?.(null);
55
- }, [serializedContext, setPageContext]);
56
-
57
- return null;
58
- }
1
+ "use client";
2
+
3
+ import React, { createContext, useContext, useEffect, useMemo, useState } from "react";
4
+
5
+ export type CortexAiContentType = "page" | "post" | "product";
6
+
7
+ export type CortexAiPageContext = {
8
+ contentType: CortexAiContentType;
9
+ currentEditor?: {
10
+ blockId?: number | string | null;
11
+ blockType?: string | null;
12
+ field?: string | null;
13
+ };
14
+ entityId: number | string;
15
+ languageId?: number | null;
16
+ slug?: string | null;
17
+ title?: string | null;
18
+ translationGroupId?: string | null;
19
+ };
20
+
21
+ type CortexAiPageContextValue = {
22
+ pageContext: CortexAiPageContext | null;
23
+ setPageContext: (context: CortexAiPageContext | null) => void;
24
+ };
25
+
26
+ const CortexAiPageContextStore = createContext<CortexAiPageContextValue | null>(null);
27
+
28
+ export function CortexAiPageContextProvider({ children }: { children: React.ReactNode }) {
29
+ const [pageContext, setPageContext] = useState<CortexAiPageContext | null>(null);
30
+ const value = useMemo(() => ({ pageContext, setPageContext }), [pageContext]);
31
+
32
+ return (
33
+ <CortexAiPageContextStore.Provider value={value}>
34
+ {children}
35
+ </CortexAiPageContextStore.Provider>
36
+ );
37
+ }
38
+
39
+ export function useCortexAiPageContext() {
40
+ return useContext(CortexAiPageContextStore);
41
+ }
42
+
43
+ export function CortexAiPageContextRegistrar({
44
+ context,
45
+ }: {
46
+ context: CortexAiPageContext;
47
+ }) {
48
+ const store = useCortexAiPageContext();
49
+ const setPageContext = store?.setPageContext;
50
+ const serializedContext = JSON.stringify(context);
51
+
52
+ useEffect(() => {
53
+ setPageContext?.(context);
54
+ return () => setPageContext?.(null);
55
+ }, [serializedContext, setPageContext]);
56
+
57
+ return null;
58
+ }
@@ -28,7 +28,16 @@ type Media = Database["public"]["Tables"]["media"]["Row"];
28
28
  interface FeatureImageFieldProps {
29
29
  initialImageId?: string | null;
30
30
  initialImageUrl?: string | null;
31
- onImageIdChange?: (imageId: string | null) => void;
31
+ /**
32
+ * Reports a selection or a removal to the parent form.
33
+ *
34
+ * The resolved URL is handed over alongside the id because this field has already
35
+ * computed it for its own thumbnail, and the parent otherwise has no way to learn it
36
+ * until the server round-trips the new `feature_image_id` back into
37
+ * `initialImageUrl`. `PageForm` and `PostForm` use it to keep their share-card preview
38
+ * honest the instant an image is picked; the id remains the only persisted half.
39
+ */
40
+ onImageIdChange?: (imageId: string | null, imageUrl: string | null) => void;
32
41
  uploadFolder: string;
33
42
  }
34
43
 
@@ -103,13 +112,13 @@ export default function FeatureImageField({
103
112
  }
104
113
 
105
114
  setSelectedFeatureImage({ id: image.id, url: imageUrl });
106
- onImageIdChange?.(image.id);
115
+ onImageIdChange?.(image.id, imageUrl);
107
116
  setIsModalOpen(false);
108
117
  };
109
118
 
110
119
  const handleRemoveImage = () => {
111
120
  setSelectedFeatureImage({ id: null, url: null });
112
- onImageIdChange?.(null);
121
+ onImageIdChange?.(null, null);
113
122
  };
114
123
 
115
124
  const handleImageSelectKeyDown = (event: KeyboardEvent<HTMLDivElement>, image: Media) => {
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
 
3
- import { useEffect, useState } from "react"
3
+ import { useEffect, useState } from "react"
4
4
  import { useAuth } from '../../../context/AuthContext';
5
5
  import { usePathname } from "next/navigation"
6
6
  import { toast } from "react-hot-toast"
@@ -29,18 +29,18 @@ interface FeedbackModalProps {
29
29
  sidebarOpen?: boolean
30
30
  }
31
31
 
32
- export function FeedbackModal({ sidebarOpen = true }: FeedbackModalProps) {
33
- const [mounted, setMounted] = useState(false)
34
- const [open, setOpen] = useState(false)
35
- const [loading, setLoading] = useState(false)
36
- const [subject, setSubject] = useState("suggestion")
32
+ export function FeedbackModal({ sidebarOpen = true }: FeedbackModalProps) {
33
+ const [mounted, setMounted] = useState(false)
34
+ const [open, setOpen] = useState(false)
35
+ const [loading, setLoading] = useState(false)
36
+ const [subject, setSubject] = useState("suggestion")
37
37
  const [message, setMessage] = useState("")
38
- const { user, profile } = useAuth()
39
- const pathname = usePathname()
40
-
41
- useEffect(() => {
42
- setMounted(true)
43
- }, [])
38
+ const { user, profile } = useAuth()
39
+ const pathname = usePathname()
40
+
41
+ useEffect(() => {
42
+ setMounted(true)
43
+ }, [])
44
44
 
45
45
  const handleSubmit = async (e: React.FormEvent) => {
46
46
  e.preventDefault()
@@ -73,30 +73,30 @@ export function FeedbackModal({ sidebarOpen = true }: FeedbackModalProps) {
73
73
  } finally {
74
74
  setLoading(false)
75
75
  }
76
- }
77
-
78
- const trigger = (
79
- <button
80
- className={cn(
81
- "flex items-center gap-3 px-3 py-2 rounded-lg text-sm font-medium transition-all w-full text-left",
82
- "text-slate-600 hover:text-primary hover:bg-primary/5 dark:text-slate-300 dark:hover:bg-primary/10"
83
- )}
84
- type="button"
85
- >
86
- <MessageSquarePlus className="h-5 w-5" />
87
- {sidebarOpen && <span>Feedback</span>}
88
- </button>
89
- )
90
-
91
- if (!mounted) {
92
- return trigger
93
- }
94
-
95
- return (
96
- <Dialog open={open} onOpenChange={setOpen}>
97
- <DialogTrigger asChild>
98
- {trigger}
99
- </DialogTrigger>
76
+ }
77
+
78
+ const trigger = (
79
+ <button
80
+ className={cn(
81
+ "flex items-center gap-3 px-3 py-2 rounded-lg text-sm font-medium transition-all w-full text-left",
82
+ "text-slate-600 hover:text-primary hover:bg-primary/5 dark:text-slate-300 dark:hover:bg-primary/10"
83
+ )}
84
+ type="button"
85
+ >
86
+ <MessageSquarePlus className="h-5 w-5" />
87
+ {sidebarOpen && <span>Feedback</span>}
88
+ </button>
89
+ )
90
+
91
+ if (!mounted) {
92
+ return trigger
93
+ }
94
+
95
+ return (
96
+ <Dialog open={open} onOpenChange={setOpen}>
97
+ <DialogTrigger asChild>
98
+ {trigger}
99
+ </DialogTrigger>
100
100
  <DialogContent className="sm:max-w-[425px]">
101
101
  <DialogHeader>
102
102
  <DialogTitle>Send Feedback</DialogTitle>
@@ -1,58 +1,58 @@
1
- 'use client';
2
-
3
- import Link from 'next/link';
4
- import { useState } from 'react';
5
- import { Button } from '@nextblock-cms/ui';
6
- import { CreditCard, X } from 'lucide-react';
7
- import { useAuth } from '../../../context/AuthContext';
8
- import type { PaymentsReminder } from '../../../lib/cms/payments-reminder';
9
-
10
- /**
11
- * Shown when commerce is active but a payment provider isn't ready, so published
12
- * products cannot actually be bought. ADMIN-only: /cms/payments is an admin route, so a
13
- * WRITER would get a reminder they cannot act on. Dismissible for the session only —
14
- * this is a real revenue problem and should come back until it's fixed.
15
- */
16
- export default function PaymentsReminderBanner({ reminder }: { reminder: PaymentsReminder }) {
17
- const { isAdmin } = useAuth();
18
- const [dismissed, setDismissed] = useState(false);
19
-
20
- if (!isAdmin || dismissed) return null;
21
-
22
- const providerSummary = reminder.blocked
23
- .map(({ label, missing }) => (missing.length ? `${label} (missing: ${missing.join(', ')})` : label))
24
- .join(' and ');
25
-
26
- return (
27
- <div className="mb-6 flex items-start gap-3 rounded-lg border border-amber-300 bg-amber-50 px-4 py-3 text-amber-900 dark:border-amber-700/60 dark:bg-amber-900/20 dark:text-amber-200">
28
- <CreditCard className="mt-0.5 h-5 w-5 shrink-0" />
29
- <div className="min-w-0 flex-1">
30
- <p className="text-sm font-medium">
31
- Your store can&rsquo;t take payments yet.
32
- </p>
33
- <p className="text-xs opacity-90">
34
- {providerSummary} still needs setting up.{' '}
35
- {reminder.affectedProducts > 0
36
- ? `${reminder.affectedProducts} published ${
37
- reminder.affectedProducts === 1 ? 'product' : 'products'
38
- } cannot be bought — visitors see a "Contact the seller" form instead of Add to cart.`
39
- : 'Products you publish will show visitors a "Contact the seller" form instead of Add to cart.'}
40
- </p>
41
- </div>
42
- <div className="flex shrink-0 items-center gap-2">
43
- <Button asChild size="sm" variant="outline" className="border-amber-400">
44
- <Link href="/cms/payments">Set up payments</Link>
45
- </Button>
46
- <Button
47
- variant="ghost"
48
- size="icon"
49
- onClick={() => setDismissed(true)}
50
- aria-label="Dismiss for now"
51
- className="h-8 w-8"
52
- >
53
- <X className="h-4 w-4" />
54
- </Button>
55
- </div>
56
- </div>
57
- );
58
- }
1
+ 'use client';
2
+
3
+ import Link from 'next/link';
4
+ import { useState } from 'react';
5
+ import { Button } from '@nextblock-cms/ui';
6
+ import { CreditCard, X } from 'lucide-react';
7
+ import { useAuth } from '../../../context/AuthContext';
8
+ import type { PaymentsReminder } from '../../../lib/cms/payments-reminder';
9
+
10
+ /**
11
+ * Shown when commerce is active but a payment provider isn't ready, so published
12
+ * products cannot actually be bought. ADMIN-only: /cms/payments is an admin route, so a
13
+ * WRITER would get a reminder they cannot act on. Dismissible for the session only —
14
+ * this is a real revenue problem and should come back until it's fixed.
15
+ */
16
+ export default function PaymentsReminderBanner({ reminder }: { reminder: PaymentsReminder }) {
17
+ const { isAdmin } = useAuth();
18
+ const [dismissed, setDismissed] = useState(false);
19
+
20
+ if (!isAdmin || dismissed) return null;
21
+
22
+ const providerSummary = reminder.blocked
23
+ .map(({ label, missing }) => (missing.length ? `${label} (missing: ${missing.join(', ')})` : label))
24
+ .join(' and ');
25
+
26
+ return (
27
+ <div className="mb-6 flex items-start gap-3 rounded-lg border border-amber-300 bg-amber-50 px-4 py-3 text-amber-900 dark:border-amber-700/60 dark:bg-amber-900/20 dark:text-amber-200">
28
+ <CreditCard className="mt-0.5 h-5 w-5 shrink-0" />
29
+ <div className="min-w-0 flex-1">
30
+ <p className="text-sm font-medium">
31
+ Your store can&rsquo;t take payments yet.
32
+ </p>
33
+ <p className="text-xs opacity-90">
34
+ {providerSummary} still needs setting up.{' '}
35
+ {reminder.affectedProducts > 0
36
+ ? `${reminder.affectedProducts} published ${
37
+ reminder.affectedProducts === 1 ? 'product' : 'products'
38
+ } cannot be bought — visitors see a "Contact the seller" form instead of Add to cart.`
39
+ : 'Products you publish will show visitors a "Contact the seller" form instead of Add to cart.'}
40
+ </p>
41
+ </div>
42
+ <div className="flex shrink-0 items-center gap-2">
43
+ <Button asChild size="sm" variant="outline" className="border-amber-400">
44
+ <Link href="/cms/payments">Set up payments</Link>
45
+ </Button>
46
+ <Button
47
+ variant="ghost"
48
+ size="icon"
49
+ onClick={() => setDismissed(true)}
50
+ aria-label="Dismiss for now"
51
+ className="h-8 w-8"
52
+ >
53
+ <X className="h-4 w-4" />
54
+ </Button>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
@@ -1,62 +1,62 @@
1
- import { Badge } from "@nextblock-cms/ui";
2
- import {
3
- LIVE_STATUS,
4
- resolveVisibilityState,
5
- type PublishableType,
6
- type VisibilityState,
7
- } from "@nextblock-cms/utils";
8
-
9
- /**
10
- * Status badge for the CMS list views.
11
- *
12
- * Reads the same (status, published_at) pair as the editor's top-bar control, so a
13
- * scheduled row is labelled "Scheduled" here instead of claiming to be published
14
- * while its URL still 404s.
15
- */
16
-
17
- const LABEL: Record<VisibilityState, string> = {
18
- draft: "Draft",
19
- scheduled: "Scheduled",
20
- published: "Published",
21
- archived: "Archived",
22
- };
23
-
24
- const CLASS_NAME: Record<VisibilityState, string> = {
25
- published:
26
- "bg-green-100 text-green-700 dark:bg-green-700/30 dark:text-green-300 dark:border-green-700/50",
27
- scheduled:
28
- "bg-amber-100 text-amber-700 dark:bg-amber-700/30 dark:text-amber-300 dark:border-amber-700/50",
29
- draft:
30
- "bg-yellow-100 text-yellow-700 dark:bg-yellow-700/30 dark:text-yellow-300 dark:border-yellow-700/50",
31
- archived:
32
- "bg-slate-100 text-slate-700 dark:bg-slate-700/30 dark:text-slate-300 dark:border-slate-600",
33
- };
34
-
35
- const VARIANT: Record<VisibilityState, "default" | "secondary" | "destructive"> = {
36
- published: "default",
37
- scheduled: "secondary",
38
- draft: "secondary",
39
- archived: "destructive",
40
- };
41
-
42
- export default function VisibilityBadge({
43
- type,
44
- status,
45
- publishedAt,
46
- }: {
47
- type: PublishableType;
48
- status: string;
49
- publishedAt?: string | null;
50
- }) {
51
- const state = resolveVisibilityState({
52
- status,
53
- publishedAt,
54
- liveStatus: LIVE_STATUS[type],
55
- });
56
-
57
- return (
58
- <Badge variant={VARIANT[state]} className={CLASS_NAME[state]}>
59
- {LABEL[state]}
60
- </Badge>
61
- );
62
- }
1
+ import { Badge } from "@nextblock-cms/ui";
2
+ import {
3
+ LIVE_STATUS,
4
+ resolveVisibilityState,
5
+ type PublishableType,
6
+ type VisibilityState,
7
+ } from "@nextblock-cms/utils";
8
+
9
+ /**
10
+ * Status badge for the CMS list views.
11
+ *
12
+ * Reads the same (status, published_at) pair as the editor's top-bar control, so a
13
+ * scheduled row is labelled "Scheduled" here instead of claiming to be published
14
+ * while its URL still 404s.
15
+ */
16
+
17
+ const LABEL: Record<VisibilityState, string> = {
18
+ draft: "Draft",
19
+ scheduled: "Scheduled",
20
+ published: "Published",
21
+ archived: "Archived",
22
+ };
23
+
24
+ const CLASS_NAME: Record<VisibilityState, string> = {
25
+ published:
26
+ "bg-green-100 text-green-700 dark:bg-green-700/30 dark:text-green-300 dark:border-green-700/50",
27
+ scheduled:
28
+ "bg-amber-100 text-amber-700 dark:bg-amber-700/30 dark:text-amber-300 dark:border-amber-700/50",
29
+ draft:
30
+ "bg-yellow-100 text-yellow-700 dark:bg-yellow-700/30 dark:text-yellow-300 dark:border-yellow-700/50",
31
+ archived:
32
+ "bg-slate-100 text-slate-700 dark:bg-slate-700/30 dark:text-slate-300 dark:border-slate-600",
33
+ };
34
+
35
+ const VARIANT: Record<VisibilityState, "default" | "secondary" | "destructive"> = {
36
+ published: "default",
37
+ scheduled: "secondary",
38
+ draft: "secondary",
39
+ archived: "destructive",
40
+ };
41
+
42
+ export default function VisibilityBadge({
43
+ type,
44
+ status,
45
+ publishedAt,
46
+ }: {
47
+ type: PublishableType;
48
+ status: string;
49
+ publishedAt?: string | null;
50
+ }) {
51
+ const state = resolveVisibilityState({
52
+ status,
53
+ publishedAt,
54
+ liveStatus: LIVE_STATUS[type],
55
+ });
56
+
57
+ return (
58
+ <Badge variant={VARIANT[state]} className={CLASS_NAME[state]}>
59
+ {LABEL[state]}
60
+ </Badge>
61
+ );
62
+ }