@btst/stack 1.0.1 → 1.1.1

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 (282) hide show
  1. package/README.md +156 -709
  2. package/dist/api/index.cjs +2 -1
  3. package/dist/api/index.d.cts +4 -3
  4. package/dist/api/index.d.mts +4 -3
  5. package/dist/api/index.d.ts +4 -3
  6. package/dist/api/index.mjs +1 -1
  7. package/dist/client/components/compose.cjs +68 -0
  8. package/dist/client/components/compose.mjs +65 -0
  9. package/dist/client/components/error-boundary.cjs +24 -0
  10. package/dist/client/components/error-boundary.mjs +22 -0
  11. package/dist/client/components/index.cjs +10 -0
  12. package/dist/client/components/index.d.cts +52 -0
  13. package/dist/client/components/index.d.mts +52 -0
  14. package/dist/client/components/index.d.ts +52 -0
  15. package/dist/client/components/index.mjs +2 -0
  16. package/dist/client/index.cjs +24 -5
  17. package/dist/client/index.d.cts +125 -8
  18. package/dist/client/index.d.mts +125 -8
  19. package/dist/client/index.d.ts +125 -8
  20. package/dist/client/index.mjs +21 -4
  21. package/dist/client/meta-utils.cjs +162 -0
  22. package/dist/client/meta-utils.mjs +160 -0
  23. package/dist/client/path-utils.cjs +15 -0
  24. package/dist/client/path-utils.mjs +13 -0
  25. package/dist/client/sitemap-utils.cjs +14 -0
  26. package/dist/client/sitemap-utils.mjs +12 -0
  27. package/dist/context/index.cjs +6 -63
  28. package/dist/context/index.d.cts +21 -24
  29. package/dist/context/index.d.mts +21 -24
  30. package/dist/context/index.d.ts +21 -24
  31. package/dist/context/index.mjs +1 -61
  32. package/dist/context/provider.cjs +51 -0
  33. package/dist/context/provider.mjs +46 -0
  34. package/dist/index.cjs +2 -3
  35. package/dist/index.d.cts +3 -2
  36. package/dist/index.d.mts +3 -2
  37. package/dist/index.d.ts +3 -2
  38. package/dist/index.mjs +1 -2
  39. package/dist/plugins/api/index.cjs +13 -0
  40. package/dist/plugins/api/index.d.cts +40 -0
  41. package/dist/plugins/api/index.d.mts +40 -0
  42. package/dist/plugins/api/index.d.ts +40 -0
  43. package/dist/plugins/api/index.mjs +8 -0
  44. package/dist/plugins/blog/api/index.cjs +11 -0
  45. package/dist/plugins/blog/api/index.d.cts +7 -0
  46. package/dist/plugins/blog/api/index.d.mts +7 -0
  47. package/dist/plugins/blog/api/index.d.ts +7 -0
  48. package/dist/plugins/blog/api/index.mjs +2 -0
  49. package/dist/plugins/blog/api/plugin.cjs +569 -0
  50. package/dist/plugins/blog/api/plugin.mjs +565 -0
  51. package/dist/plugins/blog/client/components/forms/image-field.cjs +133 -0
  52. package/dist/plugins/blog/client/components/forms/image-field.mjs +131 -0
  53. package/dist/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
  54. package/dist/plugins/blog/client/components/forms/markdown-editor.cjs +106 -0
  55. package/dist/plugins/blog/client/components/forms/markdown-editor.mjs +104 -0
  56. package/dist/plugins/blog/client/components/forms/post-forms.cjs +401 -0
  57. package/dist/plugins/blog/client/components/forms/post-forms.mjs +398 -0
  58. package/dist/plugins/blog/client/components/forms/tags-multiselect.cjs +71 -0
  59. package/dist/plugins/blog/client/components/forms/tags-multiselect.mjs +65 -0
  60. package/dist/plugins/blog/client/components/index.cjs +17 -0
  61. package/dist/plugins/blog/client/components/index.d.cts +22 -0
  62. package/dist/plugins/blog/client/components/index.d.mts +22 -0
  63. package/dist/plugins/blog/client/components/index.d.ts +22 -0
  64. package/dist/plugins/blog/client/components/index.mjs +12 -0
  65. package/dist/plugins/blog/client/components/loading/form-page-skeleton.cjs +62 -0
  66. package/dist/plugins/blog/client/components/loading/form-page-skeleton.mjs +60 -0
  67. package/dist/plugins/blog/client/components/loading/index.cjs +20 -0
  68. package/dist/plugins/blog/client/components/loading/index.mjs +16 -0
  69. package/dist/plugins/blog/client/components/loading/list-page-skeleton.cjs +26 -0
  70. package/dist/plugins/blog/client/components/loading/list-page-skeleton.mjs +24 -0
  71. package/dist/plugins/blog/client/components/loading/page-header-skeleton.cjs +13 -0
  72. package/dist/plugins/blog/client/components/loading/page-header-skeleton.mjs +11 -0
  73. package/dist/plugins/blog/client/components/loading/post-card-skeleton.cjs +22 -0
  74. package/dist/plugins/blog/client/components/loading/post-card-skeleton.mjs +20 -0
  75. package/dist/plugins/blog/client/components/loading/post-page-skeleton.cjs +56 -0
  76. package/dist/plugins/blog/client/components/loading/post-page-skeleton.mjs +54 -0
  77. package/dist/plugins/blog/client/components/pages/404-page.cjs +19 -0
  78. package/dist/plugins/blog/client/components/pages/404-page.mjs +17 -0
  79. package/dist/plugins/blog/client/components/pages/edit-post-page.cjs +41 -0
  80. package/dist/plugins/blog/client/components/pages/edit-post-page.internal.cjs +57 -0
  81. package/dist/plugins/blog/client/components/pages/edit-post-page.internal.mjs +55 -0
  82. package/dist/plugins/blog/client/components/pages/edit-post-page.mjs +39 -0
  83. package/dist/plugins/blog/client/components/pages/home-page.cjs +41 -0
  84. package/dist/plugins/blog/client/components/pages/home-page.internal.cjs +61 -0
  85. package/dist/plugins/blog/client/components/pages/home-page.internal.mjs +59 -0
  86. package/dist/plugins/blog/client/components/pages/home-page.mjs +39 -0
  87. package/dist/plugins/blog/client/components/pages/new-post-page.cjs +37 -0
  88. package/dist/plugins/blog/client/components/pages/new-post-page.internal.cjs +53 -0
  89. package/dist/plugins/blog/client/components/pages/new-post-page.internal.mjs +51 -0
  90. package/dist/plugins/blog/client/components/pages/new-post-page.mjs +35 -0
  91. package/dist/plugins/blog/client/components/pages/post-page.cjs +39 -0
  92. package/dist/plugins/blog/client/components/pages/post-page.internal.cjs +101 -0
  93. package/dist/plugins/blog/client/components/pages/post-page.internal.mjs +99 -0
  94. package/dist/plugins/blog/client/components/pages/post-page.mjs +37 -0
  95. package/dist/plugins/blog/client/components/pages/tag-page.cjs +39 -0
  96. package/dist/plugins/blog/client/components/pages/tag-page.internal.cjs +61 -0
  97. package/dist/plugins/blog/client/components/pages/tag-page.internal.mjs +59 -0
  98. package/dist/plugins/blog/client/components/pages/tag-page.mjs +37 -0
  99. package/dist/plugins/blog/client/components/shared/better-blog-attribution.cjs +24 -0
  100. package/dist/plugins/blog/client/components/shared/better-blog-attribution.mjs +22 -0
  101. package/dist/plugins/blog/client/components/shared/default-error.cjs +18 -0
  102. package/dist/plugins/blog/client/components/shared/default-error.mjs +16 -0
  103. package/dist/plugins/blog/client/components/shared/defaults.cjs +13 -0
  104. package/dist/plugins/blog/client/components/shared/defaults.mjs +10 -0
  105. package/dist/plugins/blog/client/components/shared/empty-list.cjs +21 -0
  106. package/dist/plugins/blog/client/components/shared/empty-list.mjs +19 -0
  107. package/dist/plugins/blog/client/components/shared/error-placeholder.cjs +24 -0
  108. package/dist/plugins/blog/client/components/shared/error-placeholder.mjs +22 -0
  109. package/dist/plugins/blog/client/components/shared/highlight-text.cjs +53 -0
  110. package/dist/plugins/blog/client/components/shared/highlight-text.mjs +51 -0
  111. package/dist/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
  112. package/dist/plugins/blog/client/components/shared/markdown-content.cjs +324 -0
  113. package/dist/plugins/blog/client/components/shared/markdown-content.mjs +315 -0
  114. package/dist/plugins/blog/client/components/shared/on-this-page.cjs +161 -0
  115. package/dist/plugins/blog/client/components/shared/on-this-page.mjs +158 -0
  116. package/dist/plugins/blog/client/components/shared/page-header.cjs +40 -0
  117. package/dist/plugins/blog/client/components/shared/page-header.mjs +38 -0
  118. package/dist/plugins/blog/client/components/shared/page-layout.cjs +24 -0
  119. package/dist/plugins/blog/client/components/shared/page-layout.mjs +22 -0
  120. package/dist/plugins/blog/client/components/shared/page-wrapper.cjs +23 -0
  121. package/dist/plugins/blog/client/components/shared/page-wrapper.mjs +21 -0
  122. package/dist/plugins/blog/client/components/shared/post-card.cjs +279 -0
  123. package/dist/plugins/blog/client/components/shared/post-card.mjs +277 -0
  124. package/dist/plugins/blog/client/components/shared/post-navigation.cjs +74 -0
  125. package/dist/plugins/blog/client/components/shared/post-navigation.mjs +72 -0
  126. package/dist/plugins/blog/client/components/shared/posts-list.cjs +48 -0
  127. package/dist/plugins/blog/client/components/shared/posts-list.mjs +46 -0
  128. package/dist/plugins/blog/client/components/shared/recent-posts-carousel.cjs +59 -0
  129. package/dist/plugins/blog/client/components/shared/recent-posts-carousel.mjs +57 -0
  130. package/dist/plugins/blog/client/components/shared/search-input.cjs +136 -0
  131. package/dist/plugins/blog/client/components/shared/search-input.mjs +117 -0
  132. package/dist/plugins/blog/client/components/shared/search-modal.cjs +135 -0
  133. package/dist/plugins/blog/client/components/shared/search-modal.mjs +116 -0
  134. package/dist/plugins/blog/client/components/shared/tags-list.cjs +22 -0
  135. package/dist/plugins/blog/client/components/shared/tags-list.mjs +20 -0
  136. package/dist/plugins/blog/client/components/shared/use-route-lifecycle.cjs +50 -0
  137. package/dist/plugins/blog/client/components/shared/use-route-lifecycle.mjs +48 -0
  138. package/dist/plugins/blog/client/hooks/blog-hooks.cjs +380 -0
  139. package/dist/plugins/blog/client/hooks/blog-hooks.mjs +368 -0
  140. package/dist/plugins/blog/client/hooks/index.cjs +17 -0
  141. package/dist/plugins/blog/client/hooks/index.d.cts +150 -0
  142. package/dist/plugins/blog/client/hooks/index.d.mts +150 -0
  143. package/dist/plugins/blog/client/hooks/index.d.ts +150 -0
  144. package/dist/plugins/blog/client/hooks/index.mjs +1 -0
  145. package/dist/plugins/blog/client/hooks/use-debounce.cjs +16 -0
  146. package/dist/plugins/blog/client/hooks/use-debounce.mjs +14 -0
  147. package/dist/plugins/blog/client/index.cjs +7 -0
  148. package/dist/plugins/blog/client/index.d.cts +414 -0
  149. package/dist/plugins/blog/client/index.d.mts +414 -0
  150. package/dist/plugins/blog/client/index.d.ts +414 -0
  151. package/dist/plugins/blog/client/index.mjs +1 -0
  152. package/dist/plugins/blog/client/localization/blog-card.cjs +7 -0
  153. package/dist/plugins/blog/client/localization/blog-card.mjs +5 -0
  154. package/dist/plugins/blog/client/localization/blog-common.cjs +10 -0
  155. package/dist/plugins/blog/client/localization/blog-common.mjs +8 -0
  156. package/dist/plugins/blog/client/localization/blog-forms.cjs +40 -0
  157. package/dist/plugins/blog/client/localization/blog-forms.mjs +38 -0
  158. package/dist/plugins/blog/client/localization/blog-list.cjs +18 -0
  159. package/dist/plugins/blog/client/localization/blog-list.mjs +16 -0
  160. package/dist/plugins/blog/client/localization/blog-post.cjs +13 -0
  161. package/dist/plugins/blog/client/localization/blog-post.mjs +11 -0
  162. package/dist/plugins/blog/client/localization/index.cjs +17 -0
  163. package/dist/plugins/blog/client/localization/index.mjs +15 -0
  164. package/dist/plugins/blog/client/plugin.cjs +462 -0
  165. package/dist/plugins/blog/client/plugin.mjs +460 -0
  166. package/dist/plugins/blog/client.css +3 -0
  167. package/dist/plugins/blog/db.cjs +90 -0
  168. package/dist/plugins/blog/db.mjs +88 -0
  169. package/dist/plugins/blog/query-keys.cjs +181 -0
  170. package/dist/plugins/blog/query-keys.d.cts +530 -0
  171. package/dist/plugins/blog/query-keys.d.mts +530 -0
  172. package/dist/plugins/blog/query-keys.d.ts +530 -0
  173. package/dist/plugins/blog/query-keys.mjs +179 -0
  174. package/dist/plugins/blog/schemas.cjs +39 -0
  175. package/dist/plugins/blog/schemas.mjs +35 -0
  176. package/dist/plugins/blog/style.css +22 -0
  177. package/dist/plugins/blog/utils.cjs +97 -0
  178. package/dist/plugins/blog/utils.mjs +87 -0
  179. package/dist/plugins/client/index.cjs +15 -0
  180. package/dist/plugins/client/index.d.cts +57 -0
  181. package/dist/plugins/client/index.d.mts +57 -0
  182. package/dist/plugins/client/index.d.ts +57 -0
  183. package/dist/plugins/client/index.mjs +9 -0
  184. package/dist/{shared/stack.3OUyGp_E.mjs → plugins/utils.mjs} +1 -1
  185. package/dist/shared/{stack.DORw_1ps.d.cts → stack.ByOugz9d.d.cts} +17 -1
  186. package/dist/shared/{stack.DORw_1ps.d.mts → stack.ByOugz9d.d.mts} +17 -1
  187. package/dist/shared/{stack.DORw_1ps.d.ts → stack.ByOugz9d.d.ts} +17 -1
  188. package/dist/shared/stack.CoPoHVfV.d.cts +76 -0
  189. package/dist/shared/stack.CoPoHVfV.d.mts +76 -0
  190. package/dist/shared/stack.CoPoHVfV.d.ts +76 -0
  191. package/package.json +102 -14
  192. package/src/__tests__/plugins.test.tsx +539 -0
  193. package/src/__tests__/sitemap.test.ts +60 -0
  194. package/src/api/index.ts +75 -0
  195. package/src/client/components/compose.tsx +116 -0
  196. package/src/client/components/error-boundary.tsx +30 -0
  197. package/src/client/components/index.tsx +2 -0
  198. package/src/client/index.ts +109 -0
  199. package/src/client/meta-utils.ts +228 -0
  200. package/src/client/path-utils.ts +38 -0
  201. package/src/client/sitemap-utils.ts +46 -0
  202. package/src/context/index.ts +1 -0
  203. package/src/context/provider.tsx +157 -0
  204. package/src/index.ts +1 -0
  205. package/src/plugins/api/index.ts +50 -0
  206. package/src/plugins/blog/api/index.ts +2 -0
  207. package/src/plugins/blog/api/plugin.ts +759 -0
  208. package/src/plugins/blog/client/components/forms/image-field.tsx +165 -0
  209. package/src/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
  210. package/src/plugins/blog/client/components/forms/markdown-editor.tsx +136 -0
  211. package/src/plugins/blog/client/components/forms/post-forms.tsx +531 -0
  212. package/src/plugins/blog/client/components/forms/tags-multiselect.tsx +79 -0
  213. package/src/plugins/blog/client/components/index.tsx +11 -0
  214. package/src/plugins/blog/client/components/loading/form-page-skeleton.tsx +75 -0
  215. package/src/plugins/blog/client/components/loading/index.tsx +27 -0
  216. package/src/plugins/blog/client/components/loading/list-page-skeleton.tsx +38 -0
  217. package/src/plugins/blog/client/components/loading/page-header-skeleton.tsx +10 -0
  218. package/src/plugins/blog/client/components/loading/post-card-skeleton.tsx +30 -0
  219. package/src/plugins/blog/client/components/loading/post-page-skeleton.tsx +75 -0
  220. package/src/plugins/blog/client/components/pages/404-page.tsx +23 -0
  221. package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +60 -0
  222. package/src/plugins/blog/client/components/pages/edit-post-page.tsx +40 -0
  223. package/src/plugins/blog/client/components/pages/home-page.internal.tsx +71 -0
  224. package/src/plugins/blog/client/components/pages/home-page.tsx +42 -0
  225. package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +59 -0
  226. package/src/plugins/blog/client/components/pages/new-post-page.tsx +36 -0
  227. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +142 -0
  228. package/src/plugins/blog/client/components/pages/post-page.tsx +38 -0
  229. package/src/plugins/blog/client/components/pages/tag-page.internal.tsx +74 -0
  230. package/src/plugins/blog/client/components/pages/tag-page.tsx +38 -0
  231. package/src/plugins/blog/client/components/shared/better-blog-attribution.tsx +19 -0
  232. package/src/plugins/blog/client/components/shared/default-error.tsx +20 -0
  233. package/src/plugins/blog/client/components/shared/defaults.tsx +9 -0
  234. package/src/plugins/blog/client/components/shared/empty-list.tsx +25 -0
  235. package/src/plugins/blog/client/components/shared/error-placeholder.tsx +20 -0
  236. package/src/plugins/blog/client/components/shared/highlight-text.tsx +80 -0
  237. package/src/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
  238. package/src/plugins/blog/client/components/shared/markdown-content.tsx +448 -0
  239. package/src/plugins/blog/client/components/shared/on-this-page.tsx +234 -0
  240. package/src/plugins/blog/client/components/shared/page-header.tsx +35 -0
  241. package/src/plugins/blog/client/components/shared/page-layout.tsx +23 -0
  242. package/src/plugins/blog/client/components/shared/page-wrapper.tsx +32 -0
  243. package/src/plugins/blog/client/components/shared/post-card.tsx +308 -0
  244. package/src/plugins/blog/client/components/shared/post-navigation.tsx +98 -0
  245. package/src/plugins/blog/client/components/shared/posts-list.tsx +67 -0
  246. package/src/plugins/blog/client/components/shared/recent-posts-carousel.tsx +79 -0
  247. package/src/plugins/blog/client/components/shared/search-input.tsx +146 -0
  248. package/src/plugins/blog/client/components/shared/search-modal.tsx +162 -0
  249. package/src/plugins/blog/client/components/shared/tags-list.tsx +34 -0
  250. package/src/plugins/blog/client/components/shared/use-route-lifecycle.tsx +68 -0
  251. package/src/plugins/blog/client/hooks/blog-hooks.tsx +623 -0
  252. package/src/plugins/blog/client/hooks/index.tsx +1 -0
  253. package/src/plugins/blog/client/hooks/use-debounce.ts +43 -0
  254. package/src/plugins/blog/client/index.ts +9 -0
  255. package/src/plugins/blog/client/localization/blog-card.ts +3 -0
  256. package/src/plugins/blog/client/localization/blog-common.ts +7 -0
  257. package/src/plugins/blog/client/localization/blog-forms.ts +45 -0
  258. package/src/plugins/blog/client/localization/blog-list.ts +14 -0
  259. package/src/plugins/blog/client/localization/blog-post.ts +9 -0
  260. package/src/plugins/blog/client/localization/index.ts +15 -0
  261. package/src/plugins/blog/client/overrides.ts +123 -0
  262. package/src/plugins/blog/client/plugin.tsx +672 -0
  263. package/src/plugins/blog/client.css +3 -0
  264. package/src/plugins/blog/db.ts +90 -0
  265. package/src/plugins/blog/query-keys.ts +267 -0
  266. package/src/plugins/blog/schemas.ts +39 -0
  267. package/src/plugins/blog/style.css +22 -0
  268. package/src/plugins/blog/types.ts +37 -0
  269. package/src/plugins/blog/utils.ts +144 -0
  270. package/src/plugins/client/index.ts +53 -0
  271. package/src/plugins/index.ts +0 -0
  272. package/src/plugins/utils.ts +35 -0
  273. package/src/types.ts +209 -0
  274. package/dist/plugins/index.cjs +0 -15
  275. package/dist/plugins/index.d.cts +0 -64
  276. package/dist/plugins/index.d.mts +0 -64
  277. package/dist/plugins/index.d.ts +0 -64
  278. package/dist/plugins/index.mjs +0 -11
  279. package/dist/shared/stack.DrUAVfIH.d.cts +0 -17
  280. package/dist/shared/stack.DrUAVfIH.d.mts +0 -17
  281. package/dist/shared/stack.DrUAVfIH.d.ts +0 -17
  282. /package/dist/{shared/stack.CktCg4PJ.cjs → plugins/utils.cjs} +0 -0
@@ -0,0 +1,398 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { createPostSchema, updatePostSchema } from '../../../schemas.mjs';
4
+ import { Button } from '@workspace/ui/components/button';
5
+ import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage, FormDescription } from '@workspace/ui/components/form';
6
+ import { Input } from '@workspace/ui/components/input';
7
+ import { Switch } from '@workspace/ui/components/switch';
8
+ import { Textarea } from '@workspace/ui/components/textarea';
9
+ import { useCreatePost, useSuspensePost, useUpdatePost } from '../../hooks/blog-hooks.mjs';
10
+ import { slugify } from '../../../utils.mjs';
11
+ import { zodResolver } from '@hookform/resolvers/zod';
12
+ import { Loader2 } from 'lucide-react';
13
+ import { memo, useState, useMemo, Suspense, lazy } from 'react';
14
+ import { useForm } from 'react-hook-form';
15
+ import { toast } from 'sonner';
16
+ import { FeaturedImageField } from './image-field.mjs';
17
+ import { BLOG_LOCALIZATION } from '../../localization/index.mjs';
18
+ import { usePluginOverrides } from '@btst/stack/context';
19
+ import { EmptyList } from '../shared/empty-list.mjs';
20
+ import { TagsMultiSelect } from './tags-multiselect.mjs';
21
+
22
+ const MarkdownEditor = lazy(
23
+ () => import('./markdown-editor.mjs').then((module) => ({
24
+ default: module.MarkdownEditor
25
+ }))
26
+ );
27
+ function PostFormBody({
28
+ form,
29
+ onSubmit,
30
+ submitLabel,
31
+ onCancel,
32
+ disabled,
33
+ errorMessage,
34
+ setFeaturedImageUploading,
35
+ initialSlugTouched = false
36
+ }) {
37
+ const { localization } = usePluginOverrides("blog", {
38
+ localization: BLOG_LOCALIZATION
39
+ });
40
+ const [slugTouched, setSlugTouched] = useState(initialSlugTouched);
41
+ const nameTitle = "title";
42
+ const nameSlug = "slug";
43
+ const nameExcerpt = "excerpt";
44
+ const nameImage = "image";
45
+ const nameTags = "tags";
46
+ const nameContent = "content";
47
+ const namePublished = "published";
48
+ return /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { className: "w-full space-y-4", onSubmit: form.handleSubmit(onSubmit), children: [
49
+ errorMessage && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-200 bg-red-50 p-3 text-red-600 text-sm", children: errorMessage }),
50
+ /* @__PURE__ */ jsx(
51
+ FormField,
52
+ {
53
+ control: form.control,
54
+ name: nameTitle,
55
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
56
+ /* @__PURE__ */ jsxs(FormLabel, { children: [
57
+ localization.BLOG_FORMS_TITLE_LABEL,
58
+ /* @__PURE__ */ jsx("span", { className: "text-destructive", children: localization.BLOG_FORMS_REQUIRED_ASTERISK })
59
+ ] }),
60
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
61
+ Input,
62
+ {
63
+ placeholder: localization.BLOG_FORMS_TITLE_PLACEHOLDER,
64
+ ...field,
65
+ value: String(field.value ?? ""),
66
+ onChange: (e) => {
67
+ const newTitle = e.target.value;
68
+ field.onChange(e);
69
+ if (!slugTouched) {
70
+ form.setValue(nameSlug, slugify(newTitle));
71
+ }
72
+ }
73
+ }
74
+ ) }),
75
+ /* @__PURE__ */ jsx(FormMessage, {})
76
+ ] })
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsx(
80
+ FormField,
81
+ {
82
+ control: form.control,
83
+ name: nameSlug,
84
+ render: ({ field }) => {
85
+ const currentTitle = form.getValues(nameTitle);
86
+ const autoGeneratedSlug = slugify(String(currentTitle ?? ""));
87
+ const currentSlug = String(field.value ?? "");
88
+ return /* @__PURE__ */ jsxs(FormItem, { children: [
89
+ /* @__PURE__ */ jsx(FormLabel, { children: localization.BLOG_FORMS_SLUG_LABEL }),
90
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
91
+ Input,
92
+ {
93
+ placeholder: localization.BLOG_FORMS_SLUG_PLACEHOLDER,
94
+ ...field,
95
+ value: currentSlug,
96
+ onChange: (e) => {
97
+ const newSlug = e.target.value;
98
+ field.onChange(e);
99
+ if (newSlug !== autoGeneratedSlug) {
100
+ setSlugTouched(true);
101
+ }
102
+ }
103
+ }
104
+ ) }),
105
+ /* @__PURE__ */ jsx(FormMessage, {})
106
+ ] });
107
+ }
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsx(
111
+ FormField,
112
+ {
113
+ control: form.control,
114
+ name: nameExcerpt,
115
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-col", children: [
116
+ /* @__PURE__ */ jsxs(FormLabel, { children: [
117
+ localization.BLOG_FORMS_EXCERPT_LABEL,
118
+ /* @__PURE__ */ jsx("span", { className: "text-destructive", children: localization.BLOG_FORMS_REQUIRED_ASTERISK })
119
+ ] }),
120
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
121
+ Textarea,
122
+ {
123
+ placeholder: localization.BLOG_FORMS_EXCERPT_PLACEHOLDER,
124
+ className: "min-h-20",
125
+ value: String(field.value ?? ""),
126
+ onChange: field.onChange
127
+ }
128
+ ) }),
129
+ /* @__PURE__ */ jsx(FormDescription, {}),
130
+ /* @__PURE__ */ jsx(FormMessage, {})
131
+ ] })
132
+ }
133
+ ),
134
+ /* @__PURE__ */ jsx(
135
+ FormField,
136
+ {
137
+ control: form.control,
138
+ name: nameImage,
139
+ render: ({ field }) => /* @__PURE__ */ jsx(
140
+ FeaturedImageField,
141
+ {
142
+ isRequired: false,
143
+ value: String(field.value ?? ""),
144
+ onChange: field.onChange,
145
+ setFeaturedImageUploading
146
+ }
147
+ )
148
+ }
149
+ ),
150
+ /* @__PURE__ */ jsx(
151
+ FormField,
152
+ {
153
+ control: form.control,
154
+ name: nameTags,
155
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-col", children: [
156
+ /* @__PURE__ */ jsx(FormLabel, { children: localization.BLOG_FORMS_TAGS_LABEL }),
157
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
158
+ TagsMultiSelect,
159
+ {
160
+ value: Array.isArray(field.value) ? field.value : [],
161
+ onChange: field.onChange,
162
+ placeholder: localization.BLOG_FORMS_TAGS_PLACEHOLDER
163
+ }
164
+ ) }),
165
+ /* @__PURE__ */ jsx(FormDescription, {}),
166
+ /* @__PURE__ */ jsx(FormMessage, {})
167
+ ] })
168
+ }
169
+ ),
170
+ /* @__PURE__ */ jsx(
171
+ FormField,
172
+ {
173
+ control: form.control,
174
+ name: nameContent,
175
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-col", children: [
176
+ /* @__PURE__ */ jsxs(FormLabel, { children: [
177
+ localization.BLOG_FORMS_CONTENT_LABEL,
178
+ /* @__PURE__ */ jsx("span", { className: "text-destructive", children: localization.BLOG_FORMS_REQUIRED_ASTERISK })
179
+ ] }),
180
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
181
+ Suspense,
182
+ {
183
+ fallback: /* @__PURE__ */ jsx("div", { className: "min-h-80 max-w-full border-input rounded-md border shadow-xs flex items-center justify-center bg-muted/50", children: /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }),
184
+ children: /* @__PURE__ */ jsx(
185
+ MarkdownEditor,
186
+ {
187
+ className: "min-h-80 max-w-full border-input rounded-md border shadow-xs",
188
+ value: typeof field.value === "string" ? field.value : "",
189
+ onChange: (content) => {
190
+ field.onChange(content);
191
+ }
192
+ }
193
+ )
194
+ }
195
+ ) }),
196
+ /* @__PURE__ */ jsx(FormDescription, {}),
197
+ /* @__PURE__ */ jsx(FormMessage, {})
198
+ ] })
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsx(
202
+ FormField,
203
+ {
204
+ control: form.control,
205
+ name: namePublished,
206
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm", children: [
207
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
208
+ /* @__PURE__ */ jsx(FormLabel, { children: localization.BLOG_FORMS_PUBLISHED_LABEL }),
209
+ /* @__PURE__ */ jsx(FormDescription, { children: localization.BLOG_FORMS_PUBLISHED_DESCRIPTION })
210
+ ] }),
211
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
212
+ Switch,
213
+ {
214
+ checked: !!field.value,
215
+ onCheckedChange: field.onChange
216
+ }
217
+ ) })
218
+ ] })
219
+ }
220
+ ),
221
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-4", children: [
222
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled, children: submitLabel }),
223
+ /* @__PURE__ */ jsx(
224
+ Button,
225
+ {
226
+ variant: "outline",
227
+ onClick: onCancel,
228
+ disabled,
229
+ type: "button",
230
+ children: localization.BLOG_FORMS_CANCEL_BUTTON
231
+ }
232
+ )
233
+ ] })
234
+ ] }) });
235
+ }
236
+ const CustomPostCreateSchema = createPostSchema.omit({
237
+ createdAt: true,
238
+ updatedAt: true,
239
+ publishedAt: true
240
+ });
241
+ const CustomPostUpdateSchema = updatePostSchema.omit({
242
+ id: true,
243
+ createdAt: true,
244
+ updatedAt: true,
245
+ publishedAt: true
246
+ });
247
+ const addPostFormPropsAreEqual = (prevProps, nextProps) => {
248
+ if (prevProps.onClose !== nextProps.onClose) return false;
249
+ if (prevProps.onSuccess !== nextProps.onSuccess) return false;
250
+ return true;
251
+ };
252
+ const AddPostFormComponent = ({ onClose, onSuccess }) => {
253
+ const [featuredImageUploading, setFeaturedImageUploading] = useState(false);
254
+ const { localization } = usePluginOverrides("blog", {
255
+ localization: BLOG_LOCALIZATION
256
+ });
257
+ const schema = CustomPostCreateSchema;
258
+ const {
259
+ mutateAsync: createPost,
260
+ isPending: isCreatingPost,
261
+ error: createPostError
262
+ } = useCreatePost();
263
+ const onSubmit = async (data) => {
264
+ const slug = data.slug || slugify(data.title);
265
+ const createdPost = await createPost({
266
+ title: data.title,
267
+ content: data.content,
268
+ excerpt: data.excerpt ?? "",
269
+ slug,
270
+ published: data.published ?? false,
271
+ publishedAt: data.published ? /* @__PURE__ */ new Date() : void 0,
272
+ image: data.image,
273
+ tags: data.tags || []
274
+ });
275
+ toast.success(localization.BLOG_FORMS_TOAST_CREATE_SUCCESS);
276
+ onSuccess({ published: createdPost?.published ?? false });
277
+ };
278
+ const form = useForm({
279
+ resolver: zodResolver(schema),
280
+ defaultValues: {
281
+ title: "",
282
+ content: "",
283
+ excerpt: "",
284
+ slug: void 0,
285
+ published: false,
286
+ image: "",
287
+ tags: []
288
+ }
289
+ });
290
+ return /* @__PURE__ */ jsx(
291
+ PostFormBody,
292
+ {
293
+ form,
294
+ onSubmit,
295
+ submitLabel: isCreatingPost ? localization.BLOG_FORMS_SUBMIT_CREATE_PENDING : localization.BLOG_FORMS_SUBMIT_CREATE_IDLE,
296
+ onCancel: onClose,
297
+ disabled: isCreatingPost || featuredImageUploading,
298
+ errorMessage: createPostError?.message,
299
+ setFeaturedImageUploading
300
+ }
301
+ );
302
+ };
303
+ const AddPostForm = memo(AddPostFormComponent, addPostFormPropsAreEqual);
304
+ const editPostFormPropsAreEqual = (prevProps, nextProps) => {
305
+ if (prevProps.postSlug !== nextProps.postSlug) return false;
306
+ if (prevProps.onClose !== nextProps.onClose) return false;
307
+ if (prevProps.onSuccess !== nextProps.onSuccess) return false;
308
+ return true;
309
+ };
310
+ const EditPostFormComponent = ({
311
+ postSlug,
312
+ onClose,
313
+ onSuccess
314
+ }) => {
315
+ const [featuredImageUploading, setFeaturedImageUploading] = useState(false);
316
+ const { localization } = usePluginOverrides("blog", {
317
+ localization: BLOG_LOCALIZATION
318
+ });
319
+ const { post } = useSuspensePost(postSlug);
320
+ const initialData = useMemo(() => {
321
+ if (!post) return {};
322
+ return {
323
+ title: post.title,
324
+ content: post.content,
325
+ excerpt: post.excerpt,
326
+ slug: post.slug,
327
+ published: post.published,
328
+ image: post.image || "",
329
+ tags: post.tags.map((tag) => ({
330
+ id: tag.id,
331
+ name: tag.name,
332
+ slug: tag.slug
333
+ }))
334
+ };
335
+ }, [post]);
336
+ const schema = CustomPostUpdateSchema;
337
+ const {
338
+ mutateAsync: updatePost,
339
+ isPending: isUpdatingPost,
340
+ error: updatePostError
341
+ } = useUpdatePost();
342
+ const onSubmit = async (data) => {
343
+ const updatedPost = await updatePost({
344
+ id: post.id,
345
+ data: {
346
+ id: post.id,
347
+ title: data.title,
348
+ content: data.content,
349
+ excerpt: data.excerpt ?? "",
350
+ slug: data.slug,
351
+ published: data.published ?? false,
352
+ publishedAt: data.published && !post?.published ? /* @__PURE__ */ new Date() : post?.publishedAt ? new Date(post.publishedAt) : void 0,
353
+ image: data.image,
354
+ tags: data.tags || []
355
+ }
356
+ });
357
+ toast.success(localization.BLOG_FORMS_TOAST_UPDATE_SUCCESS);
358
+ onSuccess({
359
+ slug: updatedPost?.slug ?? "",
360
+ published: updatedPost?.published ?? false
361
+ });
362
+ };
363
+ const form = useForm({
364
+ resolver: zodResolver(schema),
365
+ defaultValues: {
366
+ title: "",
367
+ content: "",
368
+ excerpt: "",
369
+ slug: "",
370
+ published: false,
371
+ image: "",
372
+ tags: []
373
+ },
374
+ values: initialData
375
+ });
376
+ if (!post) {
377
+ return /* @__PURE__ */ jsx(EmptyList, { message: localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION });
378
+ }
379
+ return /* @__PURE__ */ jsx(
380
+ PostFormBody,
381
+ {
382
+ form,
383
+ onSubmit,
384
+ submitLabel: isUpdatingPost ? localization.BLOG_FORMS_SUBMIT_UPDATE_PENDING : localization.BLOG_FORMS_SUBMIT_UPDATE_IDLE,
385
+ onCancel: onClose,
386
+ disabled: isUpdatingPost || featuredImageUploading,
387
+ errorMessage: updatePostError?.message,
388
+ setFeaturedImageUploading,
389
+ initialSlugTouched: !!post?.slug
390
+ }
391
+ );
392
+ };
393
+ const EditPostForm = memo(
394
+ EditPostFormComponent,
395
+ editPostFormPropsAreEqual
396
+ );
397
+
398
+ export { AddPostForm, EditPostForm };
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const jsxRuntime = require('react/jsx-runtime');
4
+ const MultipleSelector = require('@workspace/ui/components/multi-select');
5
+ const blogHooks = require('../../hooks/blog-hooks.cjs');
6
+
7
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
8
+
9
+ const MultipleSelector__default = /*#__PURE__*/_interopDefaultCompat(MultipleSelector);
10
+
11
+ function TagsMultiSelect({
12
+ value,
13
+ onChange,
14
+ placeholder
15
+ }) {
16
+ const { tags } = blogHooks.useTags();
17
+ const tagMap = /* @__PURE__ */ new Map();
18
+ const idToTagMap = /* @__PURE__ */ new Map();
19
+ (tags || []).forEach((tag) => {
20
+ tagMap.set(tag.name.toLowerCase(), tag);
21
+ tagMap.set(tag.slug, tag);
22
+ idToTagMap.set(tag.id, tag);
23
+ });
24
+ const options = (tags || []).map((tag) => ({
25
+ value: tag.id,
26
+ label: tag.name
27
+ }));
28
+ const selectedOptions = (value || []).map((tag) => {
29
+ if ("id" in tag && tag.id) {
30
+ return {
31
+ value: tag.id,
32
+ label: tag.name
33
+ };
34
+ }
35
+ const existingTag = tagMap.get(tag.name.toLowerCase());
36
+ return {
37
+ value: existingTag?.id || tag.name,
38
+ label: tag.name
39
+ };
40
+ });
41
+ const handleChange = (newOptions) => {
42
+ const tagObjects = newOptions.map((option) => {
43
+ const existingTag = idToTagMap.get(option.value) || Array.from(tagMap.values()).find(
44
+ (tag) => tag.name.toLowerCase() === option.value.toLowerCase()
45
+ );
46
+ if (existingTag) {
47
+ return {
48
+ id: existingTag.id,
49
+ name: existingTag.name,
50
+ slug: existingTag.slug
51
+ };
52
+ }
53
+ return { name: option.value };
54
+ });
55
+ onChange(tagObjects);
56
+ };
57
+ return /* @__PURE__ */ jsxRuntime.jsx(
58
+ MultipleSelector__default,
59
+ {
60
+ value: selectedOptions,
61
+ onChange: handleChange,
62
+ placeholder: placeholder ?? "Search or create tags...",
63
+ options,
64
+ creatable: true,
65
+ hidePlaceholderWhenSelected: true,
66
+ className: "w-full"
67
+ }
68
+ );
69
+ }
70
+
71
+ exports.TagsMultiSelect = TagsMultiSelect;
@@ -0,0 +1,65 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import MultipleSelector from '@workspace/ui/components/multi-select';
3
+ import { useTags } from '../../hooks/blog-hooks.mjs';
4
+
5
+ function TagsMultiSelect({
6
+ value,
7
+ onChange,
8
+ placeholder
9
+ }) {
10
+ const { tags } = useTags();
11
+ const tagMap = /* @__PURE__ */ new Map();
12
+ const idToTagMap = /* @__PURE__ */ new Map();
13
+ (tags || []).forEach((tag) => {
14
+ tagMap.set(tag.name.toLowerCase(), tag);
15
+ tagMap.set(tag.slug, tag);
16
+ idToTagMap.set(tag.id, tag);
17
+ });
18
+ const options = (tags || []).map((tag) => ({
19
+ value: tag.id,
20
+ label: tag.name
21
+ }));
22
+ const selectedOptions = (value || []).map((tag) => {
23
+ if ("id" in tag && tag.id) {
24
+ return {
25
+ value: tag.id,
26
+ label: tag.name
27
+ };
28
+ }
29
+ const existingTag = tagMap.get(tag.name.toLowerCase());
30
+ return {
31
+ value: existingTag?.id || tag.name,
32
+ label: tag.name
33
+ };
34
+ });
35
+ const handleChange = (newOptions) => {
36
+ const tagObjects = newOptions.map((option) => {
37
+ const existingTag = idToTagMap.get(option.value) || Array.from(tagMap.values()).find(
38
+ (tag) => tag.name.toLowerCase() === option.value.toLowerCase()
39
+ );
40
+ if (existingTag) {
41
+ return {
42
+ id: existingTag.id,
43
+ name: existingTag.name,
44
+ slug: existingTag.slug
45
+ };
46
+ }
47
+ return { name: option.value };
48
+ });
49
+ onChange(tagObjects);
50
+ };
51
+ return /* @__PURE__ */ jsx(
52
+ MultipleSelector,
53
+ {
54
+ value: selectedOptions,
55
+ onChange: handleChange,
56
+ placeholder: placeholder ?? "Search or create tags...",
57
+ options,
58
+ creatable: true,
59
+ hidePlaceholderWhenSelected: true,
60
+ className: "w-full"
61
+ }
62
+ );
63
+ }
64
+
65
+ export { TagsMultiSelect };
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const homePage = require('./pages/home-page.cjs');
5
+ const newPostPage = require('./pages/new-post-page.cjs');
6
+ const postPage = require('./pages/post-page.cjs');
7
+ const editPostPage = require('./pages/edit-post-page.cjs');
8
+
9
+ const PostListPage = homePage.HomePageComponent;
10
+ const NewPostPage = newPostPage.NewPostPageComponent;
11
+ const PostPage = postPage.PostPageComponent;
12
+ const EditPostPage = editPostPage.EditPostPageComponent;
13
+
14
+ exports.EditPostPage = EditPostPage;
15
+ exports.NewPostPage = NewPostPage;
16
+ exports.PostListPage = PostListPage;
17
+ exports.PostPage = PostPage;
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ declare function HomePageComponent({ published, }: {
4
+ published?: boolean;
5
+ }): react_jsx_runtime.JSX.Element;
6
+
7
+ declare function NewPostPageComponent(): react_jsx_runtime.JSX.Element;
8
+
9
+ declare function PostPageComponent({ slug }: {
10
+ slug: string;
11
+ }): react_jsx_runtime.JSX.Element;
12
+
13
+ declare function EditPostPageComponent({ slug }: {
14
+ slug: string;
15
+ }): react_jsx_runtime.JSX.Element;
16
+
17
+ declare const PostListPage: typeof HomePageComponent;
18
+ declare const NewPostPage: typeof NewPostPageComponent;
19
+ declare const PostPage: typeof PostPageComponent;
20
+ declare const EditPostPage: typeof EditPostPageComponent;
21
+
22
+ export { EditPostPage, NewPostPage, PostListPage, PostPage };
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ declare function HomePageComponent({ published, }: {
4
+ published?: boolean;
5
+ }): react_jsx_runtime.JSX.Element;
6
+
7
+ declare function NewPostPageComponent(): react_jsx_runtime.JSX.Element;
8
+
9
+ declare function PostPageComponent({ slug }: {
10
+ slug: string;
11
+ }): react_jsx_runtime.JSX.Element;
12
+
13
+ declare function EditPostPageComponent({ slug }: {
14
+ slug: string;
15
+ }): react_jsx_runtime.JSX.Element;
16
+
17
+ declare const PostListPage: typeof HomePageComponent;
18
+ declare const NewPostPage: typeof NewPostPageComponent;
19
+ declare const PostPage: typeof PostPageComponent;
20
+ declare const EditPostPage: typeof EditPostPageComponent;
21
+
22
+ export { EditPostPage, NewPostPage, PostListPage, PostPage };
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ declare function HomePageComponent({ published, }: {
4
+ published?: boolean;
5
+ }): react_jsx_runtime.JSX.Element;
6
+
7
+ declare function NewPostPageComponent(): react_jsx_runtime.JSX.Element;
8
+
9
+ declare function PostPageComponent({ slug }: {
10
+ slug: string;
11
+ }): react_jsx_runtime.JSX.Element;
12
+
13
+ declare function EditPostPageComponent({ slug }: {
14
+ slug: string;
15
+ }): react_jsx_runtime.JSX.Element;
16
+
17
+ declare const PostListPage: typeof HomePageComponent;
18
+ declare const NewPostPage: typeof NewPostPageComponent;
19
+ declare const PostPage: typeof PostPageComponent;
20
+ declare const EditPostPage: typeof EditPostPageComponent;
21
+
22
+ export { EditPostPage, NewPostPage, PostListPage, PostPage };
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { HomePageComponent } from './pages/home-page.mjs';
3
+ import { NewPostPageComponent } from './pages/new-post-page.mjs';
4
+ import { PostPageComponent } from './pages/post-page.mjs';
5
+ import { EditPostPageComponent } from './pages/edit-post-page.mjs';
6
+
7
+ const PostListPage = HomePageComponent;
8
+ const NewPostPage = NewPostPageComponent;
9
+ const PostPage = PostPageComponent;
10
+ const EditPostPage = EditPostPageComponent;
11
+
12
+ export { EditPostPage, NewPostPage, PostListPage, PostPage };