@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.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/admin/api/blog-client.d.ts +70 -0
- package/dist/admin/api/blog-client.d.ts.map +1 -0
- package/dist/admin/api/blog-client.js +137 -0
- package/dist/admin/api/blog-client.js.map +1 -0
- package/dist/admin/components/CategoryTreeNode.d.ts +25 -0
- package/dist/admin/components/CategoryTreeNode.d.ts.map +1 -0
- package/dist/admin/components/CategoryTreeNode.js +14 -0
- package/dist/admin/components/CategoryTreeNode.js.map +1 -0
- package/dist/admin/components/PostStatusBadge.d.ts +7 -0
- package/dist/admin/components/PostStatusBadge.d.ts.map +1 -0
- package/dist/admin/components/PostStatusBadge.js +16 -0
- package/dist/admin/components/PostStatusBadge.js.map +1 -0
- package/dist/admin/components/RelatedPostsPicker.d.ts +11 -0
- package/dist/admin/components/RelatedPostsPicker.d.ts.map +1 -0
- package/dist/admin/components/RelatedPostsPicker.js +77 -0
- package/dist/admin/components/RelatedPostsPicker.js.map +1 -0
- package/dist/admin/components/RelatedProductsPicker.d.ts +9 -0
- package/dist/admin/components/RelatedProductsPicker.d.ts.map +1 -0
- package/dist/admin/components/RelatedProductsPicker.js +66 -0
- package/dist/admin/components/RelatedProductsPicker.js.map +1 -0
- package/dist/admin/components/TagPicker.d.ts +9 -0
- package/dist/admin/components/TagPicker.d.ts.map +1 -0
- package/dist/admin/components/TagPicker.js +66 -0
- package/dist/admin/components/TagPicker.js.map +1 -0
- package/dist/admin/index.d.ts +33 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +114 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/BlogCategoryEditor.d.ts +9 -0
- package/dist/admin/pages/BlogCategoryEditor.d.ts.map +1 -0
- package/dist/admin/pages/BlogCategoryEditor.js +196 -0
- package/dist/admin/pages/BlogCategoryEditor.js.map +1 -0
- package/dist/admin/pages/BlogCategoryTreePage.d.ts +9 -0
- package/dist/admin/pages/BlogCategoryTreePage.d.ts.map +1 -0
- package/dist/admin/pages/BlogCategoryTreePage.js +122 -0
- package/dist/admin/pages/BlogCategoryTreePage.js.map +1 -0
- package/dist/admin/pages/BlogPostEditor.d.ts +9 -0
- package/dist/admin/pages/BlogPostEditor.d.ts.map +1 -0
- package/dist/admin/pages/BlogPostEditor.js +314 -0
- package/dist/admin/pages/BlogPostEditor.js.map +1 -0
- package/dist/admin/pages/BlogPostListPage.d.ts +9 -0
- package/dist/admin/pages/BlogPostListPage.d.ts.map +1 -0
- package/dist/admin/pages/BlogPostListPage.js +75 -0
- package/dist/admin/pages/BlogPostListPage.js.map +1 -0
- package/dist/admin/pages/BlogTagListPage.d.ts +9 -0
- package/dist/admin/pages/BlogTagListPage.d.ts.map +1 -0
- package/dist/admin/pages/BlogTagListPage.js +145 -0
- package/dist/admin/pages/BlogTagListPage.js.map +1 -0
- package/dist/backend/entities/blog-category-language.entity.d.ts +11 -0
- package/dist/backend/entities/blog-category-language.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-category-language.entity.js +35 -0
- package/dist/backend/entities/blog-category-language.entity.js.map +1 -0
- package/dist/backend/entities/blog-category-sales-channel.entity.d.ts +17 -0
- package/dist/backend/entities/blog-category-sales-channel.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-category-sales-channel.entity.js +48 -0
- package/dist/backend/entities/blog-category-sales-channel.entity.js.map +1 -0
- package/dist/backend/entities/blog-category.entity.d.ts +32 -0
- package/dist/backend/entities/blog-category.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-category.entity.js +113 -0
- package/dist/backend/entities/blog-category.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-category.entity.d.ts +10 -0
- package/dist/backend/entities/blog-post-category.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-category.entity.js +34 -0
- package/dist/backend/entities/blog-post-category.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-language.entity.d.ts +9 -0
- package/dist/backend/entities/blog-post-language.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-language.entity.js +33 -0
- package/dist/backend/entities/blog-post-language.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-related-post.entity.d.ts +15 -0
- package/dist/backend/entities/blog-post-related-post.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-related-post.entity.js +42 -0
- package/dist/backend/entities/blog-post-related-post.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-related-product.entity.d.ts +14 -0
- package/dist/backend/entities/blog-post-related-product.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-related-product.entity.js +41 -0
- package/dist/backend/entities/blog-post-related-product.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-sales-channel.entity.d.ts +16 -0
- package/dist/backend/entities/blog-post-sales-channel.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-sales-channel.entity.js +47 -0
- package/dist/backend/entities/blog-post-sales-channel.entity.js.map +1 -0
- package/dist/backend/entities/blog-post-tag.entity.d.ts +14 -0
- package/dist/backend/entities/blog-post-tag.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post-tag.entity.js +41 -0
- package/dist/backend/entities/blog-post-tag.entity.js.map +1 -0
- package/dist/backend/entities/blog-post.entity.d.ts +31 -0
- package/dist/backend/entities/blog-post.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-post.entity.js +106 -0
- package/dist/backend/entities/blog-post.entity.js.map +1 -0
- package/dist/backend/entities/blog-tag.entity.d.ts +18 -0
- package/dist/backend/entities/blog-tag.entity.d.ts.map +1 -0
- package/dist/backend/entities/blog-tag.entity.js +66 -0
- package/dist/backend/entities/blog-tag.entity.js.map +1 -0
- package/dist/backend/index.d.ts +100 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +182 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +12 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +148 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +6 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +72 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/services/blog-asset-references.d.ts +4 -0
- package/dist/backend/services/blog-asset-references.d.ts.map +1 -0
- package/dist/backend/services/blog-asset-references.js +79 -0
- package/dist/backend/services/blog-asset-references.js.map +1 -0
- package/dist/backend/services/blog-cache.d.ts +55 -0
- package/dist/backend/services/blog-cache.d.ts.map +1 -0
- package/dist/backend/services/blog-cache.js +111 -0
- package/dist/backend/services/blog-cache.js.map +1 -0
- package/dist/backend/services/blog-category-service.d.ts +53 -0
- package/dist/backend/services/blog-category-service.d.ts.map +1 -0
- package/dist/backend/services/blog-category-service.js +446 -0
- package/dist/backend/services/blog-category-service.js.map +1 -0
- package/dist/backend/services/blog-language-reference.d.ts +18 -0
- package/dist/backend/services/blog-language-reference.d.ts.map +1 -0
- package/dist/backend/services/blog-language-reference.js +43 -0
- package/dist/backend/services/blog-language-reference.js.map +1 -0
- package/dist/backend/services/blog-post-service.d.ts +79 -0
- package/dist/backend/services/blog-post-service.d.ts.map +1 -0
- package/dist/backend/services/blog-post-service.js +539 -0
- package/dist/backend/services/blog-post-service.js.map +1 -0
- package/dist/backend/services/blog-settings-resolver.d.ts +36 -0
- package/dist/backend/services/blog-settings-resolver.d.ts.map +1 -0
- package/dist/backend/services/blog-settings-resolver.js +68 -0
- package/dist/backend/services/blog-settings-resolver.js.map +1 -0
- package/dist/backend/services/blog-slug-collision.d.ts +35 -0
- package/dist/backend/services/blog-slug-collision.d.ts.map +1 -0
- package/dist/backend/services/blog-slug-collision.js +84 -0
- package/dist/backend/services/blog-slug-collision.js.map +1 -0
- package/dist/backend/services/blog-storefront-resolver.d.ts +107 -0
- package/dist/backend/services/blog-storefront-resolver.d.ts.map +1 -0
- package/dist/backend/services/blog-storefront-resolver.js +492 -0
- package/dist/backend/services/blog-storefront-resolver.js.map +1 -0
- package/dist/backend/services/blog-tag-service.d.ts +45 -0
- package/dist/backend/services/blog-tag-service.d.ts.map +1 -0
- package/dist/backend/services/blog-tag-service.js +198 -0
- package/dist/backend/services/blog-tag-service.js.map +1 -0
- package/dist/backend/services/seed-default-category.d.ts +25 -0
- package/dist/backend/services/seed-default-category.d.ts.map +1 -0
- package/dist/backend/services/seed-default-category.js +48 -0
- package/dist/backend/services/seed-default-category.js.map +1 -0
- package/dist/backend/services/seed-roles.d.ts +41 -0
- package/dist/backend/services/seed-roles.d.ts.map +1 -0
- package/dist/backend/services/seed-roles.js +98 -0
- package/dist/backend/services/seed-roles.js.map +1 -0
- package/dist/manifest.d.ts +226 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +236 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260506T081055_blog_init.d.ts +33 -0
- package/dist/migrations/20260506T081055_blog_init.d.ts.map +1 -0
- package/dist/migrations/20260506T081055_blog_init.js +260 -0
- package/dist/migrations/20260506T081055_blog_init.js.map +1 -0
- package/dist/migrations/20260903T101744_blog_namespace_block_names.d.ts +6 -0
- package/dist/migrations/20260903T101744_blog_namespace_block_names.d.ts.map +1 -0
- package/dist/migrations/20260903T101744_blog_namespace_block_names.js +58 -0
- package/dist/migrations/20260903T101744_blog_namespace_block_names.js.map +1 -0
- package/dist/migrations/index.d.ts +34 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +37 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/blog/index.md +199 -0
- package/i18n/en.json +166 -0
- package/i18n/pl.json +166 -0
- package/package.json +108 -0
- 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
|