@endora-commerce/mod-blog 0.100.0

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/admin/api/blog-client.d.ts +70 -0
  4. package/dist/admin/api/blog-client.d.ts.map +1 -0
  5. package/dist/admin/api/blog-client.js +137 -0
  6. package/dist/admin/api/blog-client.js.map +1 -0
  7. package/dist/admin/components/CategoryTreeNode.d.ts +25 -0
  8. package/dist/admin/components/CategoryTreeNode.d.ts.map +1 -0
  9. package/dist/admin/components/CategoryTreeNode.js +14 -0
  10. package/dist/admin/components/CategoryTreeNode.js.map +1 -0
  11. package/dist/admin/components/PostStatusBadge.d.ts +7 -0
  12. package/dist/admin/components/PostStatusBadge.d.ts.map +1 -0
  13. package/dist/admin/components/PostStatusBadge.js +16 -0
  14. package/dist/admin/components/PostStatusBadge.js.map +1 -0
  15. package/dist/admin/components/RelatedPostsPicker.d.ts +11 -0
  16. package/dist/admin/components/RelatedPostsPicker.d.ts.map +1 -0
  17. package/dist/admin/components/RelatedPostsPicker.js +77 -0
  18. package/dist/admin/components/RelatedPostsPicker.js.map +1 -0
  19. package/dist/admin/components/RelatedProductsPicker.d.ts +9 -0
  20. package/dist/admin/components/RelatedProductsPicker.d.ts.map +1 -0
  21. package/dist/admin/components/RelatedProductsPicker.js +66 -0
  22. package/dist/admin/components/RelatedProductsPicker.js.map +1 -0
  23. package/dist/admin/components/TagPicker.d.ts +9 -0
  24. package/dist/admin/components/TagPicker.d.ts.map +1 -0
  25. package/dist/admin/components/TagPicker.js +66 -0
  26. package/dist/admin/components/TagPicker.js.map +1 -0
  27. package/dist/admin/index.d.ts +33 -0
  28. package/dist/admin/index.d.ts.map +1 -0
  29. package/dist/admin/index.js +114 -0
  30. package/dist/admin/index.js.map +1 -0
  31. package/dist/admin/pages/BlogCategoryEditor.d.ts +9 -0
  32. package/dist/admin/pages/BlogCategoryEditor.d.ts.map +1 -0
  33. package/dist/admin/pages/BlogCategoryEditor.js +196 -0
  34. package/dist/admin/pages/BlogCategoryEditor.js.map +1 -0
  35. package/dist/admin/pages/BlogCategoryTreePage.d.ts +9 -0
  36. package/dist/admin/pages/BlogCategoryTreePage.d.ts.map +1 -0
  37. package/dist/admin/pages/BlogCategoryTreePage.js +122 -0
  38. package/dist/admin/pages/BlogCategoryTreePage.js.map +1 -0
  39. package/dist/admin/pages/BlogPostEditor.d.ts +9 -0
  40. package/dist/admin/pages/BlogPostEditor.d.ts.map +1 -0
  41. package/dist/admin/pages/BlogPostEditor.js +314 -0
  42. package/dist/admin/pages/BlogPostEditor.js.map +1 -0
  43. package/dist/admin/pages/BlogPostListPage.d.ts +9 -0
  44. package/dist/admin/pages/BlogPostListPage.d.ts.map +1 -0
  45. package/dist/admin/pages/BlogPostListPage.js +75 -0
  46. package/dist/admin/pages/BlogPostListPage.js.map +1 -0
  47. package/dist/admin/pages/BlogTagListPage.d.ts +9 -0
  48. package/dist/admin/pages/BlogTagListPage.d.ts.map +1 -0
  49. package/dist/admin/pages/BlogTagListPage.js +145 -0
  50. package/dist/admin/pages/BlogTagListPage.js.map +1 -0
  51. package/dist/backend/entities/blog-category-language.entity.d.ts +11 -0
  52. package/dist/backend/entities/blog-category-language.entity.d.ts.map +1 -0
  53. package/dist/backend/entities/blog-category-language.entity.js +35 -0
  54. package/dist/backend/entities/blog-category-language.entity.js.map +1 -0
  55. package/dist/backend/entities/blog-category-sales-channel.entity.d.ts +17 -0
  56. package/dist/backend/entities/blog-category-sales-channel.entity.d.ts.map +1 -0
  57. package/dist/backend/entities/blog-category-sales-channel.entity.js +48 -0
  58. package/dist/backend/entities/blog-category-sales-channel.entity.js.map +1 -0
  59. package/dist/backend/entities/blog-category.entity.d.ts +32 -0
  60. package/dist/backend/entities/blog-category.entity.d.ts.map +1 -0
  61. package/dist/backend/entities/blog-category.entity.js +113 -0
  62. package/dist/backend/entities/blog-category.entity.js.map +1 -0
  63. package/dist/backend/entities/blog-post-category.entity.d.ts +10 -0
  64. package/dist/backend/entities/blog-post-category.entity.d.ts.map +1 -0
  65. package/dist/backend/entities/blog-post-category.entity.js +34 -0
  66. package/dist/backend/entities/blog-post-category.entity.js.map +1 -0
  67. package/dist/backend/entities/blog-post-language.entity.d.ts +9 -0
  68. package/dist/backend/entities/blog-post-language.entity.d.ts.map +1 -0
  69. package/dist/backend/entities/blog-post-language.entity.js +33 -0
  70. package/dist/backend/entities/blog-post-language.entity.js.map +1 -0
  71. package/dist/backend/entities/blog-post-related-post.entity.d.ts +15 -0
  72. package/dist/backend/entities/blog-post-related-post.entity.d.ts.map +1 -0
  73. package/dist/backend/entities/blog-post-related-post.entity.js +42 -0
  74. package/dist/backend/entities/blog-post-related-post.entity.js.map +1 -0
  75. package/dist/backend/entities/blog-post-related-product.entity.d.ts +14 -0
  76. package/dist/backend/entities/blog-post-related-product.entity.d.ts.map +1 -0
  77. package/dist/backend/entities/blog-post-related-product.entity.js +41 -0
  78. package/dist/backend/entities/blog-post-related-product.entity.js.map +1 -0
  79. package/dist/backend/entities/blog-post-sales-channel.entity.d.ts +16 -0
  80. package/dist/backend/entities/blog-post-sales-channel.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/blog-post-sales-channel.entity.js +47 -0
  82. package/dist/backend/entities/blog-post-sales-channel.entity.js.map +1 -0
  83. package/dist/backend/entities/blog-post-tag.entity.d.ts +14 -0
  84. package/dist/backend/entities/blog-post-tag.entity.d.ts.map +1 -0
  85. package/dist/backend/entities/blog-post-tag.entity.js +41 -0
  86. package/dist/backend/entities/blog-post-tag.entity.js.map +1 -0
  87. package/dist/backend/entities/blog-post.entity.d.ts +31 -0
  88. package/dist/backend/entities/blog-post.entity.d.ts.map +1 -0
  89. package/dist/backend/entities/blog-post.entity.js +106 -0
  90. package/dist/backend/entities/blog-post.entity.js.map +1 -0
  91. package/dist/backend/entities/blog-tag.entity.d.ts +18 -0
  92. package/dist/backend/entities/blog-tag.entity.d.ts.map +1 -0
  93. package/dist/backend/entities/blog-tag.entity.js +66 -0
  94. package/dist/backend/entities/blog-tag.entity.js.map +1 -0
  95. package/dist/backend/index.d.ts +100 -0
  96. package/dist/backend/index.d.ts.map +1 -0
  97. package/dist/backend/index.js +182 -0
  98. package/dist/backend/index.js.map +1 -0
  99. package/dist/backend/routes.admin.d.ts +12 -0
  100. package/dist/backend/routes.admin.d.ts.map +1 -0
  101. package/dist/backend/routes.admin.js +148 -0
  102. package/dist/backend/routes.admin.js.map +1 -0
  103. package/dist/backend/routes.storefront.d.ts +6 -0
  104. package/dist/backend/routes.storefront.d.ts.map +1 -0
  105. package/dist/backend/routes.storefront.js +72 -0
  106. package/dist/backend/routes.storefront.js.map +1 -0
  107. package/dist/backend/services/blog-asset-references.d.ts +4 -0
  108. package/dist/backend/services/blog-asset-references.d.ts.map +1 -0
  109. package/dist/backend/services/blog-asset-references.js +79 -0
  110. package/dist/backend/services/blog-asset-references.js.map +1 -0
  111. package/dist/backend/services/blog-cache.d.ts +55 -0
  112. package/dist/backend/services/blog-cache.d.ts.map +1 -0
  113. package/dist/backend/services/blog-cache.js +111 -0
  114. package/dist/backend/services/blog-cache.js.map +1 -0
  115. package/dist/backend/services/blog-category-service.d.ts +53 -0
  116. package/dist/backend/services/blog-category-service.d.ts.map +1 -0
  117. package/dist/backend/services/blog-category-service.js +446 -0
  118. package/dist/backend/services/blog-category-service.js.map +1 -0
  119. package/dist/backend/services/blog-language-reference.d.ts +18 -0
  120. package/dist/backend/services/blog-language-reference.d.ts.map +1 -0
  121. package/dist/backend/services/blog-language-reference.js +43 -0
  122. package/dist/backend/services/blog-language-reference.js.map +1 -0
  123. package/dist/backend/services/blog-post-service.d.ts +79 -0
  124. package/dist/backend/services/blog-post-service.d.ts.map +1 -0
  125. package/dist/backend/services/blog-post-service.js +539 -0
  126. package/dist/backend/services/blog-post-service.js.map +1 -0
  127. package/dist/backend/services/blog-settings-resolver.d.ts +36 -0
  128. package/dist/backend/services/blog-settings-resolver.d.ts.map +1 -0
  129. package/dist/backend/services/blog-settings-resolver.js +68 -0
  130. package/dist/backend/services/blog-settings-resolver.js.map +1 -0
  131. package/dist/backend/services/blog-slug-collision.d.ts +35 -0
  132. package/dist/backend/services/blog-slug-collision.d.ts.map +1 -0
  133. package/dist/backend/services/blog-slug-collision.js +84 -0
  134. package/dist/backend/services/blog-slug-collision.js.map +1 -0
  135. package/dist/backend/services/blog-storefront-resolver.d.ts +107 -0
  136. package/dist/backend/services/blog-storefront-resolver.d.ts.map +1 -0
  137. package/dist/backend/services/blog-storefront-resolver.js +492 -0
  138. package/dist/backend/services/blog-storefront-resolver.js.map +1 -0
  139. package/dist/backend/services/blog-tag-service.d.ts +45 -0
  140. package/dist/backend/services/blog-tag-service.d.ts.map +1 -0
  141. package/dist/backend/services/blog-tag-service.js +198 -0
  142. package/dist/backend/services/blog-tag-service.js.map +1 -0
  143. package/dist/backend/services/seed-default-category.d.ts +25 -0
  144. package/dist/backend/services/seed-default-category.d.ts.map +1 -0
  145. package/dist/backend/services/seed-default-category.js +48 -0
  146. package/dist/backend/services/seed-default-category.js.map +1 -0
  147. package/dist/backend/services/seed-roles.d.ts +41 -0
  148. package/dist/backend/services/seed-roles.d.ts.map +1 -0
  149. package/dist/backend/services/seed-roles.js +98 -0
  150. package/dist/backend/services/seed-roles.js.map +1 -0
  151. package/dist/manifest.d.ts +226 -0
  152. package/dist/manifest.d.ts.map +1 -0
  153. package/dist/manifest.js +236 -0
  154. package/dist/manifest.js.map +1 -0
  155. package/dist/migrations/20260506T081055_blog_init.d.ts +33 -0
  156. package/dist/migrations/20260506T081055_blog_init.d.ts.map +1 -0
  157. package/dist/migrations/20260506T081055_blog_init.js +260 -0
  158. package/dist/migrations/20260506T081055_blog_init.js.map +1 -0
  159. package/dist/migrations/20260903T101744_blog_namespace_block_names.d.ts +6 -0
  160. package/dist/migrations/20260903T101744_blog_namespace_block_names.d.ts.map +1 -0
  161. package/dist/migrations/20260903T101744_blog_namespace_block_names.js +58 -0
  162. package/dist/migrations/20260903T101744_blog_namespace_block_names.js.map +1 -0
  163. package/dist/migrations/index.d.ts +34 -0
  164. package/dist/migrations/index.d.ts.map +1 -0
  165. package/dist/migrations/index.js +37 -0
  166. package/dist/migrations/index.js.map +1 -0
  167. package/docs/blog/index.md +199 -0
  168. package/i18n/en.json +166 -0
  169. package/i18n/pl.json +166 -0
  170. package/package.json +108 -0
  171. package/tailwind.css +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ <!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
2
+
3
+ # @endora-commerce/mod-blog
4
+
5
+ Multi-channel, multi-language blog with categories, tags, and Page Builder posts.
6
+
7
+ ## What this is
8
+
9
+ An **Endora Commerce module package**. Its module id is `blog` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
10
+
11
+ A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
12
+
13
+ ## Entry points
14
+
15
+ | Import | Contents |
16
+ | --- | --- |
17
+ | `@endora-commerce/mod-blog` | the module manifest — its id, version, dependencies, settings and activation |
18
+ | `@endora-commerce/mod-blog/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
19
+ | `@endora-commerce/mod-blog/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
20
+ | `@endora-commerce/mod-blog/migrations` | the module’s own schema migrations, in the order the platform runs them |
21
+ | `@endora-commerce/mod-blog/tailwind.css` | the Tailwind source declaration for the admin code above |
22
+
23
+ ## Depends on
24
+
25
+ Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
26
+
27
+ **Endora packages**
28
+
29
+ - `@endora-commerce/admin-kit` — *optional*
30
+ - `@endora-commerce/contracts`
31
+ - `@endora-commerce/mod-cms` — *optional*
32
+ - `@endora-commerce/page-builder-core`
33
+ - `@endora-commerce/platform`
34
+
35
+ **Third-party**
36
+
37
+ - `@measured/puck` ^0 — *optional*
38
+ - `@mikro-orm/core` ^6
39
+ - `@mikro-orm/migrations` ^6
40
+ - `@mikro-orm/postgresql` ^6
41
+ - `fastify` ^5
42
+ - `ioredis` ^5
43
+ - `react` ^19 — *optional*
44
+ - `react-router-dom` ^7 — *optional*
45
+ - `zod` ^4
46
+
47
+ ## What the tarball carries
48
+
49
+ - `dist/` — the compiled JavaScript and its type declarations
50
+ - `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
51
+ - `docs/` — the package’s own pages in the Endora Commerce documentation site
52
+ - `tailwind.css` — the Tailwind source declaration
53
+
54
+ ## Install
55
+
56
+ ```bash
57
+ pnpm add @endora-commerce/mod-blog
58
+ ```
59
+
60
+ ## Licence
61
+
62
+ MIT — the text is in `LICENSE`, beside this file.
@@ -0,0 +1,70 @@
1
+ import type { BlogCategoryDetail, BlogCategoryTreeNode, BlogCategoryTreeMove, BlogPostDetail, BlogPostInboundReferencesResponse, BlogPostStatus, BlogPostSummary, BlogTagDetail, BlogTagInboundReferencesResponse, CreateBlogCategoryRequest, CreateBlogPostRequest, CreateBlogTagRequest, PatchBlogCategoryRequest, PatchBlogPostRequest, PatchBlogTagRequest, PutBlogCategoryDescriptionRequest, PutBlogPostContentRequest } from '@endora-commerce/contracts';
2
+ export type { BlogCategoryDetail, BlogCategoryTreeNode, BlogCategoryTreeMove, BlogPostDetail, BlogPostInboundReferencesResponse, BlogPostStatus, BlogPostSummary, BlogTagDetail, BlogTagInboundReferencesResponse, CreateBlogCategoryRequest, CreateBlogPostRequest, CreateBlogTagRequest, PatchBlogCategoryRequest, PatchBlogPostRequest, PatchBlogTagRequest, PutBlogCategoryDescriptionRequest, PutBlogPostContentRequest, };
3
+ export interface ListBlogPostsQuery {
4
+ q?: string;
5
+ status?: BlogPostStatus;
6
+ salesChannelId?: string;
7
+ categoryId?: string;
8
+ tagId?: string;
9
+ language?: string;
10
+ page?: number;
11
+ perPage?: number;
12
+ }
13
+ export interface ListBlogPostsResponse {
14
+ data: BlogPostSummary[];
15
+ pagination: {
16
+ page: number;
17
+ perPage: number;
18
+ totalPages: number;
19
+ totalItems: number;
20
+ };
21
+ }
22
+ export interface ListBlogTagsQuery {
23
+ q?: string;
24
+ page?: number;
25
+ perPage?: number;
26
+ }
27
+ export interface ListBlogTagsResponse {
28
+ data: BlogTagDetail[];
29
+ pagination: {
30
+ page: number;
31
+ perPage: number;
32
+ totalPages: number;
33
+ totalItems: number;
34
+ };
35
+ }
36
+ export declare const blogClient: {
37
+ listPosts(query?: ListBlogPostsQuery): Promise<ListBlogPostsResponse>;
38
+ createPost(body: CreateBlogPostRequest): Promise<BlogPostDetail>;
39
+ getPost(id: string): Promise<BlogPostDetail>;
40
+ patchPost(id: string, body: PatchBlogPostRequest): Promise<BlogPostDetail>;
41
+ putPostContent(id: string, body: PutBlogPostContentRequest): Promise<BlogPostDetail>;
42
+ setPostTags(id: string, tagIds: string[], version: number): Promise<BlogPostDetail>;
43
+ setPostRelatedPosts(id: string, relatedPostIds: string[], version: number): Promise<BlogPostDetail>;
44
+ setPostRelatedProducts(id: string, productIds: string[], version: number): Promise<BlogPostDetail>;
45
+ publishPost(id: string, version: number): Promise<BlogPostDetail>;
46
+ unpublishPost(id: string, version: number): Promise<BlogPostDetail>;
47
+ archivePost(id: string, version: number): Promise<BlogPostDetail>;
48
+ deletePost(id: string, version: number): Promise<{
49
+ detachedFromParents: string[];
50
+ }>;
51
+ getPostInboundReferences(id: string): Promise<BlogPostInboundReferencesResponse>;
52
+ getCategoryTree(): Promise<{
53
+ tree: BlogCategoryTreeNode[];
54
+ }>;
55
+ getCategory(id: string): Promise<BlogCategoryDetail>;
56
+ createCategory(body: CreateBlogCategoryRequest): Promise<BlogCategoryDetail>;
57
+ patchCategory(id: string, body: PatchBlogCategoryRequest): Promise<BlogCategoryDetail>;
58
+ putCategoryDescription(id: string, body: PutBlogCategoryDescriptionRequest): Promise<BlogCategoryDetail>;
59
+ applyCategoryTreeMoves(moves: BlogCategoryTreeMove[]): Promise<{
60
+ tree: BlogCategoryTreeNode[];
61
+ }>;
62
+ deleteCategory(id: string, version: number): Promise<void>;
63
+ listTags(query?: ListBlogTagsQuery): Promise<ListBlogTagsResponse>;
64
+ getTag(id: string): Promise<BlogTagDetail>;
65
+ createTag(body: CreateBlogTagRequest): Promise<BlogTagDetail>;
66
+ patchTag(id: string, body: PatchBlogTagRequest): Promise<BlogTagDetail>;
67
+ deleteTag(id: string, version: number): Promise<void>;
68
+ getTagInboundReferences(id: string): Promise<BlogTagInboundReferencesResponse>;
69
+ };
70
+ //# sourceMappingURL=blog-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-client.d.ts","sourceRoot":"","sources":["../../../src/admin/api/blog-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { apiClient } from '@endora-commerce/admin-kit/lib';
2
+ function postQueryString(query) {
3
+ const params = new URLSearchParams();
4
+ if (query.q)
5
+ params.set('q', query.q);
6
+ if (query.status)
7
+ params.set('status', query.status);
8
+ if (query.salesChannelId)
9
+ params.set('salesChannelId', query.salesChannelId);
10
+ if (query.categoryId)
11
+ params.set('categoryId', query.categoryId);
12
+ if (query.tagId)
13
+ params.set('tagId', query.tagId);
14
+ if (query.language)
15
+ params.set('language', query.language);
16
+ if (query.page !== undefined)
17
+ params.set('page', String(query.page));
18
+ if (query.perPage !== undefined)
19
+ params.set('perPage', String(query.perPage));
20
+ const out = params.toString();
21
+ return out ? `?${out}` : '';
22
+ }
23
+ function tagQueryString(query) {
24
+ const params = new URLSearchParams();
25
+ if (query.q)
26
+ params.set('q', query.q);
27
+ if (query.page !== undefined)
28
+ params.set('page', String(query.page));
29
+ if (query.perPage !== undefined)
30
+ params.set('perPage', String(query.perPage));
31
+ const out = params.toString();
32
+ return out ? `?${out}` : '';
33
+ }
34
+ export const blogClient = {
35
+ // ── Posts ──────────────────────────────────────────────────────────
36
+ listPosts(query = {}) {
37
+ return apiClient.get(`/api/v1/admin/blog/posts${postQueryString(query)}`);
38
+ },
39
+ async createPost(body) {
40
+ const out = await apiClient.post('/api/v1/admin/blog/posts', body);
41
+ return out.data;
42
+ },
43
+ async getPost(id) {
44
+ const out = await apiClient.get(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}`);
45
+ return out.data;
46
+ },
47
+ async patchPost(id, body) {
48
+ const out = await apiClient.patch(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}`, body);
49
+ return out.data;
50
+ },
51
+ async putPostContent(id, body) {
52
+ const out = await apiClient.put(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/content`, body);
53
+ return out.data;
54
+ },
55
+ async setPostTags(id, tagIds, version) {
56
+ const out = await apiClient.put(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/tags`, { tagIds, version });
57
+ return out.data;
58
+ },
59
+ async setPostRelatedPosts(id, relatedPostIds, version) {
60
+ const out = await apiClient.put(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/related-posts`, { relatedPostIds, version });
61
+ return out.data;
62
+ },
63
+ async setPostRelatedProducts(id, productIds, version) {
64
+ const out = await apiClient.put(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/related-products`, { productIds, version });
65
+ return out.data;
66
+ },
67
+ async publishPost(id, version) {
68
+ const out = await apiClient.post(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/publish`, { version });
69
+ return out.data;
70
+ },
71
+ async unpublishPost(id, version) {
72
+ const out = await apiClient.post(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/unpublish`, { version });
73
+ return out.data;
74
+ },
75
+ async archivePost(id, version) {
76
+ const out = await apiClient.post(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/archive`, { version });
77
+ return out.data;
78
+ },
79
+ async deletePost(id, version) {
80
+ const out = await apiClient.delete(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}?version=${version}`);
81
+ return out.data;
82
+ },
83
+ async getPostInboundReferences(id) {
84
+ const out = await apiClient.get(`/api/v1/admin/blog/posts/${encodeURIComponent(id)}/inbound-references`);
85
+ return out.data;
86
+ },
87
+ // ── Categories ─────────────────────────────────────────────────────
88
+ async getCategoryTree() {
89
+ return apiClient.get('/api/v1/admin/blog/categories');
90
+ },
91
+ async getCategory(id) {
92
+ const out = await apiClient.get(`/api/v1/admin/blog/categories/${encodeURIComponent(id)}`);
93
+ return out.data;
94
+ },
95
+ async createCategory(body) {
96
+ const out = await apiClient.post('/api/v1/admin/blog/categories', body);
97
+ return out.data;
98
+ },
99
+ async patchCategory(id, body) {
100
+ const out = await apiClient.patch(`/api/v1/admin/blog/categories/${encodeURIComponent(id)}`, body);
101
+ return out.data;
102
+ },
103
+ async putCategoryDescription(id, body) {
104
+ const out = await apiClient.put(`/api/v1/admin/blog/categories/${encodeURIComponent(id)}/description`, body);
105
+ return out.data;
106
+ },
107
+ async applyCategoryTreeMoves(moves) {
108
+ return apiClient.put('/api/v1/admin/blog/categories/tree', { moves });
109
+ },
110
+ async deleteCategory(id, version) {
111
+ await apiClient.delete(`/api/v1/admin/blog/categories/${encodeURIComponent(id)}?version=${version}`);
112
+ },
113
+ // ── Tags ───────────────────────────────────────────────────────────
114
+ listTags(query = {}) {
115
+ return apiClient.get(`/api/v1/admin/blog/tags${tagQueryString(query)}`);
116
+ },
117
+ async getTag(id) {
118
+ const out = await apiClient.get(`/api/v1/admin/blog/tags/${encodeURIComponent(id)}`);
119
+ return out.data;
120
+ },
121
+ async createTag(body) {
122
+ const out = await apiClient.post('/api/v1/admin/blog/tags', body);
123
+ return out.data;
124
+ },
125
+ async patchTag(id, body) {
126
+ const out = await apiClient.patch(`/api/v1/admin/blog/tags/${encodeURIComponent(id)}`, body);
127
+ return out.data;
128
+ },
129
+ async deleteTag(id, version) {
130
+ await apiClient.delete(`/api/v1/admin/blog/tags/${encodeURIComponent(id)}?version=${version}`);
131
+ },
132
+ async getTagInboundReferences(id) {
133
+ const out = await apiClient.get(`/api/v1/admin/blog/tags/${encodeURIComponent(id)}/inbound-references`);
134
+ return out.data;
135
+ },
136
+ };
137
+ //# sourceMappingURL=blog-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-client.js","sourceRoot":"","sources":["../../../src/admin/api/blog-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { BlogCategoryTreeNode as TreeNode } from '@endora-commerce/contracts';
3
+ interface NodeRowProps {
4
+ node: TreeNode;
5
+ depth: number;
6
+ canMoveUp: boolean;
7
+ canMoveDown: boolean;
8
+ onMoveUp: (node: TreeNode) => void;
9
+ onMoveDown: (node: TreeNode) => void;
10
+ onAddChild: (parentId: string) => void;
11
+ /**
12
+ * Whether the operator holds `blog.write`.
13
+ *
14
+ * The *+ Child* button navigates to `/blog/categories/new`, which takes the
15
+ * write code since feature 091's batch 16, so a read-only operator pressing
16
+ * it would reach the admin's not-found page. It is a required prop rather
17
+ * than an optional one with a permissive default: a caller that forgets it
18
+ * does not compile, which is the direction a permission gate has to fail in.
19
+ */
20
+ canCreate: boolean;
21
+ onDelete: (node: TreeNode) => void;
22
+ }
23
+ export declare function CategoryTreeNode({ node, depth, canMoveUp, canMoveDown, onMoveUp, onMoveDown, onAddChild, onDelete, canCreate, }: NodeRowProps): ReactNode;
24
+ export {};
25
+ //# sourceMappingURL=CategoryTreeNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CategoryTreeNode.d.ts","sourceRoot":"","sources":["../../../src/admin/components/CategoryTreeNode.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,oBAAoB,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AASnF,UAAU,YAAY;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;;;;;;OAQG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,GACV,EAAE,YAAY,GAAG,SAAS,CAwE1B"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link } from 'react-router-dom';
3
+ import { Badge, Button } from '@endora-commerce/admin-kit/ui';
4
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
5
+ function pickName(name, fallback) {
6
+ if (!name)
7
+ return fallback;
8
+ return name['en-US'] ?? Object.values(name)[0] ?? fallback;
9
+ }
10
+ export function CategoryTreeNode({ node, depth, canMoveUp, canMoveDown, onMoveUp, onMoveDown, onAddChild, onDelete, canCreate, }) {
11
+ const t = useTranslation('blog');
12
+ return (_jsxs("div", { className: "flex items-center gap-2 border-b py-2", style: { paddingLeft: `${depth * 24}px` }, children: [_jsx("span", { className: "font-medium", children: _jsx(Link, { to: `/blog/categories/${node.id}`, className: "text-primary hover:underline", children: pickName(node.name, node.slug) }) }), _jsx(Badge, { variant: "outline", className: "font-mono text-[10px]", children: node.slug }), !node.enabled ? (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: t('state.disabled') })) : null, node.isSystem ? (_jsx(Badge, { variant: "secondary", className: "text-[10px]", children: t('state.system') })) : null, _jsxs("span", { className: "ml-auto flex gap-1", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: !canMoveUp, onClick: () => onMoveUp(node), "aria-label": t('common.moveUp'), children: "\u2191" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: !canMoveDown, onClick: () => onMoveDown(node), "aria-label": t('common.moveDown'), children: "\u2193" }), canCreate ? (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onAddChild(node.id), children: t('categoryTree.addChild') })) : null, _jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: node.isSystem, onClick: () => onDelete(node), children: t('common.delete') })] })] }));
13
+ }
14
+ //# sourceMappingURL=CategoryTreeNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CategoryTreeNode.js","sourceRoot":"","sources":["../../../src/admin/components/CategoryTreeNode.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,SAAS,QAAQ,CAAC,IAA+C,EAAE,QAAgB;IACjF,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;AAC7D,CAAC;AAuBD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,GACI;IACb,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAEjC,OAAO,CACL,eACE,SAAS,EAAC,uCAAuC,EACjD,KAAK,EAAE,EAAE,WAAW,EAAE,GAAG,KAAK,GAAG,EAAE,IAAI,EAAE,aAEzC,eAAM,SAAS,EAAC,aAAa,YAC3B,KAAC,IAAI,IACH,EAAE,EAAE,oBAAoB,IAAI,CAAC,EAAE,EAAE,EACjC,SAAS,EAAC,8BAA8B,YAEvC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAC1B,GACF,EACP,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,uBAAuB,YACvD,IAAI,CAAC,IAAI,GACJ,EACP,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CACf,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,aAAa,YAC7C,CAAC,CAAC,gBAAgB,CAAC,GACd,CACT,CAAC,CAAC,CAAC,IAAI,EACP,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CACf,KAAC,KAAK,IAAC,OAAO,EAAC,WAAW,EAAC,SAAS,EAAC,aAAa,YAC/C,CAAC,CAAC,cAAc,CAAC,GACZ,CACT,CAAC,CAAC,CAAC,IAAI,EACR,gBAAM,SAAS,EAAC,oBAAoB,aAClC,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,CAAC,SAAS,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBACjB,CAAC,CAAC,eAAe,CAAC,uBAGvB,EACT,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,CAAC,WAAW,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gBACnB,CAAC,CAAC,iBAAiB,CAAC,uBAGzB,EACR,SAAS,CAAC,CAAC,CAAC,CACX,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,YAEjC,CAAC,CAAC,uBAAuB,CAAC,GACpB,CACV,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAE5B,CAAC,CAAC,eAAe,CAAC,GACZ,IACJ,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { BlogPostStatus } from '@endora-commerce/contracts';
3
+ export declare function PostStatusBadge({ status, active, }: {
4
+ status: BlogPostStatus;
5
+ active?: boolean;
6
+ }): ReactNode;
7
+ //# sourceMappingURL=PostStatusBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostStatusBadge.d.ts","sourceRoot":"","sources":["../../../src/admin/components/PostStatusBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAejE,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAa,GACd,EAAE;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,SAAS,CAWZ"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Badge } from '@endora-commerce/admin-kit/ui';
3
+ const VARIANT_BY_STATUS = {
4
+ draft: 'outline',
5
+ published: 'default',
6
+ archived: 'secondary',
7
+ };
8
+ const LABEL_BY_STATUS = {
9
+ draft: 'draft',
10
+ published: 'published',
11
+ archived: 'archived',
12
+ };
13
+ export function PostStatusBadge({ status, active = true, }) {
14
+ return (_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Badge, { variant: VARIANT_BY_STATUS[status], children: LABEL_BY_STATUS[status] }), !active ? (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: "inactive" })) : null] }));
15
+ }
16
+ //# sourceMappingURL=PostStatusBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostStatusBadge.js","sourceRoot":"","sources":["../../../src/admin/components/PostStatusBadge.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAEtD,MAAM,iBAAiB,GAAgE;IACrF,KAAK,EAAE,SAAS;IAChB,SAAS,EAAE,SAAS;IACpB,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF,MAAM,eAAe,GAAmC;IACtD,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACrB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,GAAG,IAAI,GAId;IACC,OAAO,CACL,gBAAM,SAAS,EAAC,gCAAgC,aAC9C,KAAC,KAAK,IAAC,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,YAAG,eAAe,CAAC,MAAM,CAAC,GAAS,EAC3E,CAAC,MAAM,CAAC,CAAC,CAAC,CACT,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,aAAa,yBAExC,CACT,CAAC,CAAC,CAAC,IAAI,IACH,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type ReactNode } from 'react';
2
+ interface RelatedPostsPickerProps {
3
+ /** Ordered list of related-post ids. */
4
+ value: string[];
5
+ /** Id of the parent post — refused as a related entry (self-reference guard). */
6
+ selfId: string;
7
+ onChange: (next: string[]) => void;
8
+ }
9
+ export declare function RelatedPostsPicker({ value, selfId, onChange, }: RelatedPostsPickerProps): ReactNode;
10
+ export {};
11
+ //# sourceMappingURL=RelatedPostsPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelatedPostsPicker.d.ts","sourceRoot":"","sources":["../../../src/admin/components/RelatedPostsPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAYzE,UAAU,uBAAuB;IAC/B,wCAAwC;IACxC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE,uBAAuB,GAAG,SAAS,CAgLrC"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Alert, AlertDescription, Badge, Button, Input, Label } from '@endora-commerce/admin-kit/ui';
4
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
5
+ import { blogClient } from '../api/blog-client.js';
6
+ import { normalize } from '@endora-commerce/admin-kit/lib';
7
+ function pickName(name, fallback) {
8
+ if (!name)
9
+ return fallback;
10
+ return name['en-US'] ?? Object.values(name)[0] ?? fallback;
11
+ }
12
+ export function RelatedPostsPicker({ value, selfId, onChange, }) {
13
+ const t = useTranslation('blog');
14
+ const [allPosts, setAllPosts] = useState([]);
15
+ const [q, setQ] = useState('');
16
+ const [loading, setLoading] = useState(true);
17
+ const [error, setError] = useState(null);
18
+ const reload = useCallback(async (search) => {
19
+ setLoading(true);
20
+ try {
21
+ const out = await blogClient.listPosts({
22
+ ...(search ? { q: search } : {}),
23
+ perPage: 50,
24
+ });
25
+ setAllPosts(out.data);
26
+ setError(null);
27
+ }
28
+ catch (err) {
29
+ setError(err instanceof Error ? err.message : String(err));
30
+ }
31
+ finally {
32
+ setLoading(false);
33
+ }
34
+ }, []);
35
+ useEffect(() => {
36
+ void reload('');
37
+ }, [reload]);
38
+ const postsById = new Map(allPosts.map((p) => [p.id, p]));
39
+ // Candidates: not the parent itself, not already attached, optionally
40
+ // matching the search query.
41
+ const needle = normalize(q);
42
+ const candidates = allPosts.filter((post) => {
43
+ if (post.id === selfId)
44
+ return false;
45
+ if (value.includes(post.id))
46
+ return false;
47
+ if (needle === '')
48
+ return true;
49
+ const haystack = `${normalize(pickName(post.name, post.slug))} ${normalize(post.slug)}`;
50
+ return haystack.includes(needle);
51
+ });
52
+ const attach = useCallback((id) => {
53
+ if (id === selfId)
54
+ return;
55
+ onChange([...value, id]);
56
+ }, [onChange, selfId, value]);
57
+ const detach = useCallback((id) => onChange(value.filter((existing) => existing !== id)), [onChange, value]);
58
+ const move = useCallback((id, dir) => {
59
+ const idx = value.indexOf(id);
60
+ if (idx < 0)
61
+ return;
62
+ const next = dir === 'up' ? idx - 1 : idx + 1;
63
+ if (next < 0 || next >= value.length)
64
+ return;
65
+ const out = [...value];
66
+ [out[idx], out[next]] = [out[next], out[idx]];
67
+ onChange(out);
68
+ }, [onChange, value]);
69
+ return (_jsxs("div", { className: "space-y-3", children: [error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, _jsxs("div", { children: [_jsx(Label, { children: t('relatedPosts.title', { count: value.length }) }), value.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('relatedPosts.empty') })) : (_jsx("div", { className: "mt-2 flex flex-col gap-2", children: value.map((id, idx) => {
70
+ const post = postsById.get(id);
71
+ return (_jsxs("div", { className: "flex items-center gap-2 rounded border px-2 py-1 text-sm", children: [_jsx("span", { className: "flex-1 font-medium", children: post ? pickName(post.name, post.slug) : t('common.loadingInline') }), _jsx(Badge, { variant: "outline", className: "font-mono text-[10px]", children: post?.slug ?? id.slice(0, 8) }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 w-7 p-0", disabled: idx === 0, onClick: () => move(id, 'up'), "aria-label": t('relatedPosts.moveUp'), children: "\u2191" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 w-7 p-0", disabled: idx === value.length - 1, onClick: () => move(id, 'down'), "aria-label": t('relatedPosts.moveDown'), children: "\u2193" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 px-2", onClick: () => detach(id), children: "\u00D7" })] }, id));
72
+ }) }))] }), _jsxs("div", { children: [_jsx(Label, { htmlFor: "related-posts-q", children: t('relatedPosts.add') }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Input, { id: "related-posts-q", value: q, onChange: (event) => setQ(event.target.value), onKeyDown: (event) => {
73
+ if (event.key === 'Enter')
74
+ void reload(q);
75
+ }, placeholder: t('relatedPosts.searchPlaceholder') }), _jsx(Button, { type: "button", variant: "outline", onClick: () => void reload(q), children: t('common.search') })] }), loading ? (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t('relatedPosts.loading') })) : candidates.length === 0 ? (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: q ? t('relatedPosts.noMatches') : t('relatedPosts.noCandidates') })) : (_jsx("div", { className: "mt-2 flex flex-col gap-1", children: candidates.slice(0, 15).map((post) => (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => attach(post.id), className: "justify-start", children: [_jsx("span", { className: "mr-2 font-mono text-[10px]", children: post.slug }), _jsx("span", { className: "text-left", children: pickName(post.name, post.slug) }), _jsx(Badge, { variant: "outline", className: "ml-auto text-[10px]", children: t(`status.${post.status}`) })] }, post.id))) }))] })] }));
76
+ }
77
+ //# sourceMappingURL=RelatedPostsPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelatedPostsPicker.js","sourceRoot":"","sources":["../../../src/admin/components/RelatedPostsPicker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type ReactNode } from 'react';
2
+ interface RelatedProductsPickerProps {
3
+ /** Ordered list of related-product ids (Catalog product UUIDs). */
4
+ value: string[];
5
+ onChange: (next: string[]) => void;
6
+ }
7
+ export declare function RelatedProductsPicker({ value, onChange, }: RelatedProductsPickerProps): ReactNode;
8
+ export {};
9
+ //# sourceMappingURL=RelatedProductsPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelatedProductsPicker.d.ts","sourceRoot":"","sources":["../../../src/admin/components/RelatedProductsPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBzE,UAAU,0BAA0B;IAClC,mEAAmE;IACnE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,QAAQ,GACT,EAAE,0BAA0B,GAAG,SAAS,CA8KxC"}
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { apiClient, normalize } from '@endora-commerce/admin-kit/lib';
4
+ import { Alert, AlertDescription, Badge, Button, Input, Label } from '@endora-commerce/admin-kit/ui';
5
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
6
+ function pickName(name, fallback) {
7
+ if (!name)
8
+ return fallback;
9
+ return name['en-US'] ?? Object.values(name)[0] ?? fallback;
10
+ }
11
+ export function RelatedProductsPicker({ value, onChange, }) {
12
+ const t = useTranslation('blog');
13
+ const [allProducts, setAllProducts] = useState([]);
14
+ const [q, setQ] = useState('');
15
+ const [loading, setLoading] = useState(true);
16
+ const [error, setError] = useState(null);
17
+ useEffect(() => {
18
+ let live = true;
19
+ apiClient
20
+ .get('/api/v1/admin/catalog/products?includeArchived=1')
21
+ .then((res) => {
22
+ if (!live)
23
+ return;
24
+ setAllProducts(res.data);
25
+ setLoading(false);
26
+ })
27
+ .catch((err) => {
28
+ if (!live)
29
+ return;
30
+ setError(err instanceof Error ? err.message : String(err));
31
+ setLoading(false);
32
+ });
33
+ return () => {
34
+ live = false;
35
+ };
36
+ }, []);
37
+ const productsById = new Map(allProducts.map((p) => [p.id, p]));
38
+ const needle = normalize(q);
39
+ const candidates = allProducts.filter((product) => {
40
+ if (value.includes(product.id))
41
+ return false;
42
+ if (needle === '')
43
+ return true;
44
+ const haystack = `${normalize(pickName(product.name, product.slug))} ${normalize(product.slug)} ${normalize(product.sku)}`;
45
+ return haystack.includes(needle);
46
+ });
47
+ const attach = useCallback((id) => onChange([...value, id]), [onChange, value]);
48
+ const detach = useCallback((id) => onChange(value.filter((existing) => existing !== id)), [onChange, value]);
49
+ const move = useCallback((id, dir) => {
50
+ const idx = value.indexOf(id);
51
+ if (idx < 0)
52
+ return;
53
+ const next = dir === 'up' ? idx - 1 : idx + 1;
54
+ if (next < 0 || next >= value.length)
55
+ return;
56
+ const out = [...value];
57
+ [out[idx], out[next]] = [out[next], out[idx]];
58
+ onChange(out);
59
+ }, [onChange, value]);
60
+ return (_jsxs("div", { className: "space-y-3", children: [error ? (_jsx(Alert, { variant: "destructive", children: _jsx(AlertDescription, { children: error }) })) : null, _jsxs("div", { children: [_jsx(Label, { children: t('relatedProducts.title', { count: value.length }) }), value.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('relatedProducts.empty') })) : (_jsx("div", { className: "mt-2 flex flex-col gap-2", children: value.map((id, idx) => {
61
+ const product = productsById.get(id);
62
+ const inactive = product?.status === 'inactive';
63
+ return (_jsxs("div", { className: `flex items-center gap-2 rounded border px-2 py-1 text-sm ${!product || inactive ? 'opacity-60' : ''}`, children: [_jsx("span", { className: "flex-1 font-medium", children: product ? pickName(product.name, product.slug) : t('relatedProducts.unknown') }), _jsx(Badge, { variant: "outline", className: "font-mono text-[10px]", children: product?.sku ?? id.slice(0, 8) }), inactive ? (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: t('status.inactive') })) : null, !product ? (_jsx(Badge, { variant: "outline", className: "text-[10px]", children: t('state.missing') })) : null, _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 w-7 p-0", disabled: idx === 0, onClick: () => move(id, 'up'), "aria-label": t('relatedProducts.moveUp'), children: "\u2191" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 w-7 p-0", disabled: idx === value.length - 1, onClick: () => move(id, 'down'), "aria-label": t('relatedProducts.moveDown'), children: "\u2193" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 px-2", onClick: () => detach(id), children: "\u00D7" })] }, id));
64
+ }) }))] }), _jsxs("div", { children: [_jsx(Label, { htmlFor: "related-products-q", children: t('relatedProducts.add') }), _jsx(Input, { id: "related-products-q", value: q, onChange: (event) => setQ(event.target.value), placeholder: t('relatedProducts.searchPlaceholder') }), loading ? (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t('relatedProducts.loading') })) : candidates.length === 0 ? (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: q ? t('relatedProducts.noMatches') : t('relatedProducts.noCandidates') })) : (_jsx("div", { className: "mt-2 flex flex-col gap-1", children: candidates.slice(0, 15).map((product) => (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => attach(product.id), className: "justify-start", children: [_jsx("span", { className: "mr-2 font-mono text-[10px]", children: product.sku }), _jsx("span", { className: "text-left", children: pickName(product.name, product.slug) }), _jsx(Badge, { variant: "outline", className: "ml-auto text-[10px]", children: t(`productStatus.${product.status}`) })] }, product.id))) }))] })] }));
65
+ }
66
+ //# sourceMappingURL=RelatedProductsPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelatedProductsPicker.js","sourceRoot":"","sources":["../../../src/admin/components/RelatedProductsPicker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type ReactNode } from 'react';
2
+ interface TagPickerProps {
3
+ /** Ordered list of currently-attached tag ids. */
4
+ value: string[];
5
+ onChange: (next: string[]) => void;
6
+ }
7
+ export declare function TagPicker({ value, onChange }: TagPickerProps): ReactNode;
8
+ export {};
9
+ //# sourceMappingURL=TagPicker.d.ts.map